mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-17 18:01:26 +08:00
feat: 对镜像进行延迟测试,并选择最优镜像
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
@@ -72,6 +73,34 @@ namespace MaaWpfGui.Services.Web
|
||||
BuildDownloaderHttpClient();
|
||||
}
|
||||
|
||||
public async Task<double> HeadAsync(Uri uri, Dictionary<string, string> extraHeader = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new HttpRequestMessage { RequestUri = uri, Method = HttpMethod.Head, };
|
||||
|
||||
if (extraHeader != null)
|
||||
{
|
||||
foreach (var kvp in extraHeader)
|
||||
{
|
||||
request.Headers.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
var response = await _client.SendAsync(request);
|
||||
stopwatch.Stop();
|
||||
response.Log();
|
||||
|
||||
return response.IsSuccessStatusCode is false ? -1.0 : stopwatch.Elapsed.TotalMilliseconds;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Failed to send GET request to {Uri}", uri);
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetStringAsync(Uri uri, Dictionary<string, string> extraHeader = null)
|
||||
{
|
||||
var response = await GetAsync(uri, extraHeader);
|
||||
@@ -96,15 +125,11 @@ namespace MaaWpfGui.Services.Web
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> GetAsync(Uri uri, Dictionary<string, string> extraHeader = null)
|
||||
public async Task<HttpResponseMessage> GetAsync(Uri uri, Dictionary<string, string> extraHeader = null, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead)
|
||||
{
|
||||
try
|
||||
{
|
||||
var request = new HttpRequestMessage
|
||||
{
|
||||
RequestUri = uri,
|
||||
Method = HttpMethod.Get,
|
||||
};
|
||||
var request = new HttpRequestMessage { RequestUri = uri, Method = HttpMethod.Get, };
|
||||
|
||||
if (extraHeader != null)
|
||||
{
|
||||
@@ -114,7 +139,7 @@ namespace MaaWpfGui.Services.Web
|
||||
}
|
||||
}
|
||||
|
||||
var response = await _client.SendAsync(request);
|
||||
var response = await _client.SendAsync(request, httpCompletionOption);
|
||||
response.Log();
|
||||
|
||||
return response.IsSuccessStatusCode is false ? null : response;
|
||||
@@ -145,7 +170,7 @@ namespace MaaWpfGui.Services.Web
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DownloadFileAsync(Uri uri, string fileName, string contentType = null)
|
||||
public async Task<bool> DownloadFileAsync(Uri uri, string fileName, string contentType = "application/octet-stream")
|
||||
{
|
||||
string fileDir = Directory.GetCurrentDirectory();
|
||||
string fileNameWithTemp = fileName + ".temp";
|
||||
@@ -153,7 +178,7 @@ namespace MaaWpfGui.Services.Web
|
||||
string fullFilePathWithTemp = Path.Combine(fileDir, fileNameWithTemp);
|
||||
_logger.Information("Start to download file from {Uri} and save to {TempPath}", uri, fullFilePathWithTemp);
|
||||
|
||||
var response = await GetAsync(uri, extraHeader: new Dictionary<string, string> { { "Accept", contentType } });
|
||||
var response = await GetAsync(uri, extraHeader: new Dictionary<string, string> { { "Accept", contentType } }, httpCompletionOption: HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
if (response is null)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,14 @@ namespace MaaWpfGui.Services.Web
|
||||
{
|
||||
public interface IHttpService
|
||||
{
|
||||
/// <summary>
|
||||
/// Test url available and return legacy
|
||||
/// </summary>
|
||||
/// <param name="uri">Target Uri</param>
|
||||
/// <param name="extraHeader">Extra HTTP Request Headers</param>
|
||||
/// <returns>Legacy in ms, -1 when response code not equal 200</returns>
|
||||
Task<double> HeadAsync(Uri uri, Dictionary<string, string> extraHeader = null);
|
||||
|
||||
/// <summary>
|
||||
/// Send HTTP GET request and get a string response
|
||||
/// </summary>
|
||||
@@ -43,7 +51,7 @@ namespace MaaWpfGui.Services.Web
|
||||
/// <param name="uri">Target Uri</param>
|
||||
/// <param name="extraHeader">Extra HTTP Request Headers</param>
|
||||
/// <returns><see cref="HttpRequestMessage"/> object</returns>
|
||||
Task<HttpResponseMessage> GetAsync(Uri uri, Dictionary<string, string> extraHeader = null);
|
||||
Task<HttpResponseMessage> GetAsync(Uri uri, Dictionary<string, string> extraHeader = null, HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead);
|
||||
|
||||
/// <summary>
|
||||
/// Send HTTP POST request and a string reponse
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
}
|
||||
|
||||
public FlowDocument UpdateInfoDoc => Markdig.Wpf.Markdown.ToFlowDocument(UpdateInfo,
|
||||
new MarkdownPipelineBuilder().UseSupportedExtensions().Build());
|
||||
new MarkdownPipelineBuilder().UseSupportedExtensions().Build());
|
||||
|
||||
private string _updateUrl;
|
||||
|
||||
@@ -199,8 +199,8 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
{
|
||||
using var toast = new ToastNotification(LocalizationHelper.GetString("NewVersionZipFileFoundTitle"));
|
||||
toast.AppendContentText(LocalizationHelper.GetString("NewVersionZipFileFoundDescDecompressing"))
|
||||
.AppendContentText(UpdateTag)
|
||||
.ShowUpdateVersion(row: 2);
|
||||
.AppendContentText(UpdateTag)
|
||||
.ShowUpdateVersion(row: 2);
|
||||
});
|
||||
|
||||
string curDir = Directory.GetCurrentDirectory();
|
||||
@@ -224,8 +224,8 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
{
|
||||
using var toast = new ToastNotification(LocalizationHelper.GetString("NewVersionZipFileBrokenTitle"));
|
||||
toast.AppendContentText(LocalizationHelper.GetString("NewVersionZipFileBrokenDescFilename") + UpdatePackageName)
|
||||
.AppendContentText(LocalizationHelper.GetString("NewVersionZipFileBrokenDescDeleted"))
|
||||
.ShowUpdateVersion();
|
||||
.AppendContentText(LocalizationHelper.GetString("NewVersionZipFileBrokenDescDeleted"))
|
||||
.ShowUpdateVersion();
|
||||
});
|
||||
return false;
|
||||
}
|
||||
@@ -422,7 +422,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
return version;
|
||||
}
|
||||
else if (SemVersion.TryParse(version, SemVersionStyles.AllowLowerV, out var semVersion) &&
|
||||
isNightlyVersion(semVersion))
|
||||
isNightlyVersion(semVersion))
|
||||
{
|
||||
// v4.6.6-1.g{Hash}
|
||||
// v4.6.7-beta.2.8.g{Hash}
|
||||
@@ -465,9 +465,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
#pragma warning restore IDE0042
|
||||
Execute.OnUIThread(() =>
|
||||
{
|
||||
using var toast = new ToastNotification((otaFound ?
|
||||
LocalizationHelper.GetString("NewVersionFoundTitle") :
|
||||
LocalizationHelper.GetString("NewVersionFoundButNoPackageTitle")) + " : " + UpdateTag);
|
||||
using var toast = new ToastNotification((otaFound ? LocalizationHelper.GetString("NewVersionFoundTitle") : LocalizationHelper.GetString("NewVersionFoundButNoPackageTitle")) + " : " + UpdateTag);
|
||||
if (goDownload)
|
||||
{
|
||||
OutputDownloadProgress(downloading: false, output: LocalizationHelper.GetString("NewVersionDownloadPreparing"));
|
||||
@@ -526,17 +524,45 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
urls.Add(rawUrl);
|
||||
}
|
||||
|
||||
foreach (var url in urls)
|
||||
_logger.Information("Start test legacy download urls");
|
||||
|
||||
// run legacy test parallel
|
||||
var tasks = urls.ConvertAll(url => Instances.HttpService.HeadAsync(new Uri(url)));
|
||||
var legacies = await Task.WhenAll(tasks);
|
||||
|
||||
// select the fastest mirror
|
||||
_logger.Information("Selecting the fastest mirror:");
|
||||
var selected = 0;
|
||||
for (int i = 0; i < legacies.Length; i++)
|
||||
{
|
||||
downloaded = await DownloadGithubAssets(url, _assetsObject);
|
||||
if (downloaded)
|
||||
if (legacies[i].Equals(-1.0))
|
||||
{
|
||||
OutputDownloadProgress(downloading: false, output: LocalizationHelper.GetString("NewVersionDownloadCompletedTitle"));
|
||||
break;
|
||||
_logger.Warning("\turl: {0} not available", urls[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
_logger.Information("\turl: {0}, legacy: {1:0.00}ms", urls[i], legacies[i]);
|
||||
if (legacies[i] < legacies[selected])
|
||||
{
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!downloaded)
|
||||
if (legacies[selected].Equals(-1.0))
|
||||
{
|
||||
_logger.Error("All mirrors are not available");
|
||||
return CheckUpdateRetT.NetworkError;
|
||||
}
|
||||
|
||||
_logger.Information("Selected mirror: {0}", urls[selected]);
|
||||
|
||||
|
||||
downloaded = await DownloadGithubAssets(urls[selected], _assetsObject);
|
||||
if (downloaded)
|
||||
{
|
||||
OutputDownloadProgress(downloading: false, output: LocalizationHelper.GetString("NewVersionDownloadCompletedTitle"));
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputDownloadProgress(downloading: false, output: LocalizationHelper.GetString("NewVersionDownloadFailedTitle"));
|
||||
Execute.OnUIThread(() =>
|
||||
@@ -544,8 +570,8 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
using var toast = new ToastNotification(LocalizationHelper.GetString("NewVersionDownloadFailedTitle"));
|
||||
toast.ButtonSystemUrl = UpdateUrl;
|
||||
toast.AppendContentText(LocalizationHelper.GetString("NewVersionDownloadFailedDesc"))
|
||||
.AddButtonLeft(openUrlToastButton.text, openUrlToastButton.action)
|
||||
.Show();
|
||||
.AddButtonLeft(openUrlToastButton.text, openUrlToastButton.action)
|
||||
.Show();
|
||||
});
|
||||
return CheckUpdateRetT.NoNeedToUpdate;
|
||||
}
|
||||
@@ -728,8 +754,8 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (string.IsNullOrEmpty(response) && retryTimes-- > 0);
|
||||
} while (string.IsNullOrEmpty(response) && retryTimes-- > 0);
|
||||
|
||||
return response;
|
||||
}
|
||||
#pragma warning restore IDE0051 // 删除未使用的私有成员
|
||||
@@ -746,9 +772,9 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
try
|
||||
{
|
||||
return await Instances.HttpService.DownloadFileAsync(
|
||||
new Uri(url),
|
||||
assetsObject["name"].ToString(),
|
||||
assetsObject["content_type"]?.ToString())
|
||||
new Uri(url),
|
||||
assetsObject["name"].ToString(),
|
||||
assetsObject["content_type"]?.ToString())
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
Reference in New Issue
Block a user