58 lines
2.1 KiB
C#
58 lines
2.1 KiB
C#
using System.Diagnostics;
|
|||
|
|
|
||
|
|
using MeWeb.Shared;
|
||
|
|
|
||
|
|
namespace MeWeb.Core.Net;
|
||
|
|
|
||
|
|
public class SpeedReport
|
||
|
|
{
|
||
|
|
public double DownMbps { get; set; }
|
||
|
|
public double UpMbps { get; set; }
|
||
|
|
public int DownBytes { get; set; }
|
||
|
|
public int UpBytes { get; set; }
|
||
|
|
public bool Limited { get; set; }
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class SpeedCheck
|
||
|
|
{
|
||
|
|
public static async Task<SpeedReport> Run(HttpClient https, LinkKind kind, CancellationToken ct)
|
||
|
|
{
|
||
|
|
var mobile = kind == LinkKind.Mobile;
|
||
|
|
var report = new SpeedReport { DownBytes = mobile ? 2 * 1024 * 1024 : 12 * 1024 * 1024, UpBytes = mobile ? 1024 * 1024 : 4 * 1024 * 1024 };
|
||
|
|
try
|
||
|
|
{
|
||
|
|
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||
|
|
timeout.CancelAfter(TimeSpan.FromSeconds(30));
|
||
|
|
var clock = Stopwatch.StartNew();
|
||
|
|
using (var response = await https.GetAsync(Endpoints.Base + Endpoints.Speed.GET_M_Down(report.DownBytes), HttpCompletionOption.ResponseHeadersRead, timeout.Token))
|
||
|
|
{
|
||
|
|
if ((int)response.StatusCode == 429)
|
||
|
|
{
|
||
|
|
report.Limited = true;
|
||
|
|
return report;
|
||
|
|
}
|
||
|
|
response.EnsureSuccessStatusCode();
|
||
|
|
await using var body = await response.Content.ReadAsStreamAsync(timeout.Token);
|
||
|
|
var buffer = new byte[64 * 1024];
|
||
|
|
long total = 0;
|
||
|
|
int read;
|
||
|
|
while ((read = await body.ReadAsync(buffer, timeout.Token)) > 0) total += read;
|
||
|
|
report.DownMbps = Mbps(total, clock.Elapsed);
|
||
|
|
}
|
||
|
|
|
||
|
|
var payload = new byte[report.UpBytes];
|
||
|
|
Random.Shared.NextBytes(payload);
|
||
|
|
clock.Restart();
|
||
|
|
using (var response = await https.PostAsync(Endpoints.Base + Endpoints.Speed.POST_Up, new ByteArrayContent(payload), timeout.Token))
|
||
|
|
{
|
||
|
|
if (response.IsSuccessStatusCode) report.UpMbps = Mbps(payload.Length, clock.Elapsed);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException or IOException && !ct.IsCancellationRequested)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
return report;
|
||
|
|
}
|
||
|
|
|
||
|
|
static double Mbps(long bytes, TimeSpan elapsed) => elapsed.TotalSeconds <= 0 ? 0 : Math.Round(bytes * 8 / elapsed.TotalSeconds / 1_000_000, 1);
|
||
|
|
}
|