diff --git a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs index 262bbb2..717b31e 100644 --- a/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs +++ b/FastGithub.ReverseProxy/KestrelServerOptionsExtensions.cs @@ -77,9 +77,9 @@ namespace FastGithub store.Close(); } } - catch (Exception ex) + catch (Exception ) { - logger.LogError($"安装根证书{caPublicCerPath}失败:{ex.Message}"); + logger.LogError($"安装根证书{caPublicCerPath}失败:请手动安装到“将所有的证书都放入下载存储”\\“受信任的根证书颁发机构”"); } } } diff --git a/FastGithub.Scanner/GithubResultScanHostedService.cs b/FastGithub.Scanner/GithubResultScanHostedService.cs index 7957c43..fa52ec3 100644 --- a/FastGithub.Scanner/GithubResultScanHostedService.cs +++ b/FastGithub.Scanner/GithubResultScanHostedService.cs @@ -37,7 +37,7 @@ namespace FastGithub while (stoppingToken.IsCancellationRequested == false) { await Task.Delay(this.options.CurrentValue.ResultScanInterval, stoppingToken); - await githubScanService.ScanResultAsync(); + await githubScanService.ScanResultAsync(stoppingToken); } } } diff --git a/FastGithub.Scanner/GithubScanResults.cs b/FastGithub.Scanner/GithubScanResults.cs index b55e721..dd052c2 100644 --- a/FastGithub.Scanner/GithubScanResults.cs +++ b/FastGithub.Scanner/GithubScanResults.cs @@ -1,18 +1,68 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; using System.Linq; using System.Net; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; namespace FastGithub.Scanner { /// - /// GithubContext集合 + /// github扫描结果 /// [Service(ServiceLifetime.Singleton)] sealed class GithubScanResults { + private const string dataFile = "FastGithub.dat"; private readonly object syncRoot = new(); private readonly List contexts = new(); + private readonly ILogger logger; + + /// + /// github扫描结果 + /// + /// + public GithubScanResults(ILogger logger) + { + this.logger = logger; + var datas = LoadDatas(logger); + foreach (var context in datas) + { + this.Add(context); + } + } + + /// + /// 从磁盘加载数据 + /// + /// + /// + private static GithubContext[] LoadDatas(ILogger logger) + { + try + { + if (File.Exists(dataFile) == true) + { + var json = File.ReadAllBytes(dataFile); + var datas = JsonSerializer.Deserialize(json); + if (datas != null) + { + return datas.Select(item => item.ToGithubContext()).ToArray(); + } + } + } + catch (Exception ex) + { + logger.LogWarning($"从{dataFile}加载数据失败:{ex.Message}"); + } + + return Array.Empty(); + } /// /// 添加GithubContext @@ -42,7 +92,7 @@ namespace FastGithub.Scanner { return this.contexts.ToArray(); } - } + } /// /// 查找最优的ip @@ -50,11 +100,11 @@ namespace FastGithub.Scanner /// /// public IPAddress? FindBestAddress(string domain) - { + { lock (this.syncRoot) { return this.contexts - .Where(item => item.Domain == domain && item.AvailableRate > 0d) + .Where(item => item.Domain == domain) .OrderByDescending(item => item.AvailableRate) .ThenByDescending(item => item.Available) .ThenBy(item => item.AvgElapsed) @@ -62,5 +112,54 @@ namespace FastGithub.Scanner .FirstOrDefault(); } } + + /// + /// 保存数据到磁盘 + /// + /// + /// + public async Task SaveDatasAsync(CancellationToken cancellationToken = default) + { + try + { + using var stream = File.OpenWrite(dataFile); + var datas = this.ToArray() + .OrderByDescending(item => item.AvailableRate) + .Select(item => GithubDomainAddress.From(item)); + + await JsonSerializer.SerializeAsync(stream, datas, cancellationToken: cancellationToken); + } + catch (Exception ex) + { + this.logger.LogWarning($"保存数据到{dataFile}失败:{ex.Message}"); + } + } + + + /// + /// github的域名与ip关系数据 + /// + private class GithubDomainAddress + { + [AllowNull] + public string Domain { get; set; } + + [AllowNull] + public string Address { get; set; } + + public GithubContext ToGithubContext() + { + return new GithubContext(this.Domain, IPAddress.Parse(this.Address)) { Available = true }; + } + + public static GithubDomainAddress From(GithubContext context) + { + return new GithubDomainAddress + { + Domain = context.Domain, + Address = context.Address.ToString() + }; + } + } } } diff --git a/FastGithub.Scanner/GithubScanService.cs b/FastGithub.Scanner/GithubScanService.cs index 5efd383..93eae5c 100644 --- a/FastGithub.Scanner/GithubScanService.cs +++ b/FastGithub.Scanner/GithubScanService.cs @@ -133,10 +133,11 @@ namespace FastGithub.Scanner } /// - /// 扫描曾经扫描到的结果 + /// 扫描历史结果 /// + /// /// - public async Task ScanResultAsync() + public async Task ScanResultAsync(CancellationToken cancellationToken) { this.logger.LogInformation("结果扫描开始.."); @@ -161,6 +162,7 @@ namespace FastGithub.Scanner } this.dnsFlushService.FlushGithubResolverCache(); this.logger.LogInformation($"结果扫描结束,共扫描{results.Length}条记录"); + await this.scanResults.SaveDatasAsync(cancellationToken); } } } diff --git a/FastGithub.Scanner/ScannerServiceCollectionExtensions.cs b/FastGithub.Scanner/ScannerServiceCollectionExtensions.cs index 51b798e..d681cc1 100644 --- a/FastGithub.Scanner/ScannerServiceCollectionExtensions.cs +++ b/FastGithub.Scanner/ScannerServiceCollectionExtensions.cs @@ -39,7 +39,7 @@ namespace FastGithub return services .AddMemoryCache() .AddServiceAndOptions(assembly, configuration) - .AddHostedService() + //.AddHostedService() .AddHostedService(); ; }