From 60784caa760ad4ec6d535eb121109da218368c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=9B=BD=E4=BC=9F?= <366193849@qq.com> Date: Tue, 28 Sep 2021 13:37:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8IDispose=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=9D=A5=E5=85=B3=E9=97=AD=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FastGithub.DomainResolve/DnsClient.cs | 8 +- FastGithub.DomainResolve/DnscryptProxy.cs | 97 +++++++++----- .../DomainResolveHostedService.cs | 35 +---- FastGithub.DomainResolve/DomainSpeedTester.cs | 125 ++++++++++-------- 4 files changed, 148 insertions(+), 117 deletions(-) diff --git a/FastGithub.DomainResolve/DnsClient.cs b/FastGithub.DomainResolve/DnsClient.cs index 8a29636..fcbd061 100644 --- a/FastGithub.DomainResolve/DnsClient.cs +++ b/FastGithub.DomainResolve/DnsClient.cs @@ -145,10 +145,16 @@ namespace FastGithub.DomainResolve RecursionDesired = true, OperationCode = OperationCode.Query }; + request.Questions.Add(new Question(new Domain(domain), RecordType.A)); var clientRequest = new ClientRequest(resolver, request); var response = await clientRequest.Resolve(cancellationToken); - return response.AnswerRecords.OfType().Select(item => item.IPAddress).ToArray(); + + return response.AnswerRecords + .OfType() + .Where(item => IPAddress.IsLoopback(item.IPAddress) == false) + .Select(item => item.IPAddress) + .ToArray(); } } } diff --git a/FastGithub.DomainResolve/DnscryptProxy.cs b/FastGithub.DomainResolve/DnscryptProxy.cs index e6cbea6..d7784ba 100644 --- a/FastGithub.DomainResolve/DnscryptProxy.cs +++ b/FastGithub.DomainResolve/DnscryptProxy.cs @@ -1,4 +1,5 @@ using FastGithub.Configuration; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Diagnostics; @@ -15,11 +16,13 @@ namespace FastGithub.DomainResolve /// /// DnscryptProxy服务 /// - sealed class DnscryptProxy + sealed class DnscryptProxy : IDisposable { private const string PATH = "dnscrypt-proxy"; private const string NAME = "dnscrypt-proxy"; + private readonly ILogger logger; + /// /// 相关进程 /// @@ -30,12 +33,38 @@ namespace FastGithub.DomainResolve /// public IPEndPoint? LocalEndPoint { get; private set; } + /// + /// DnscryptProxy服务 + /// + /// + public DnscryptProxy(ILogger logger) + { + this.logger = logger; + } + /// /// 启动dnscrypt-proxy /// /// /// public async Task StartAsync(CancellationToken cancellationToken) + { + try + { + await this.StartCoreAsync(cancellationToken); + } + catch (Exception ex) + { + this.logger.LogWarning($"{NAME}启动失败:{ex.Message}"); + } + } + + /// + /// 启动dnscrypt-proxy + /// + /// + /// + private async Task StartCoreAsync(CancellationToken cancellationToken) { var tomlPath = Path.Combine(PATH, $"{NAME}.toml"); var port = GetAvailablePort(IPAddress.Loopback.AddressFamily); @@ -70,8 +99,6 @@ namespace FastGithub.DomainResolve } } - - /// /// 获取可用的随机端口 /// @@ -113,35 +140,6 @@ namespace FastGithub.DomainResolve this.LocalEndPoint = null; } - /// - /// 停止dnscrypt-proxy - /// - /// - public bool Stop() - { - try - { - if (OperatingSystem.IsWindows()) - { - StartDnscryptProxy("-service stop")?.WaitForExit(); - StartDnscryptProxy("-service uninstall")?.WaitForExit(); - } - if (this.process != null && this.process.HasExited == false) - { - this.process.Kill(); - } - return true; - } - catch (Exception) - { - return false; - } - finally - { - this.LocalEndPoint = null; - } - } - /// /// 启动DnscryptProxy进程 /// @@ -160,6 +158,41 @@ namespace FastGithub.DomainResolve }); } + /// + /// 释放资源 + /// + public void Dispose() + { + try + { + this.Stop(); + } + catch (Exception ex) + { + this.logger.LogWarning($"{NAME}停止失败:{ex.Message }"); + } + finally + { + this.LocalEndPoint = null; + } + } + + /// + /// 停止服务 + /// + private void Stop() + { + if (OperatingSystem.IsWindows()) + { + StartDnscryptProxy("-service stop")?.WaitForExit(); + StartDnscryptProxy("-service uninstall")?.WaitForExit(); + } + if (this.process != null && this.process.HasExited == false) + { + this.process.Kill(); + } + } + /// /// 转换为字符串 /// diff --git a/FastGithub.DomainResolve/DomainResolveHostedService.cs b/FastGithub.DomainResolve/DomainResolveHostedService.cs index 3e18641..bed0acd 100644 --- a/FastGithub.DomainResolve/DomainResolveHostedService.cs +++ b/FastGithub.DomainResolve/DomainResolveHostedService.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using System; using System.Threading; using System.Threading.Tasks; @@ -13,7 +12,6 @@ namespace FastGithub.DomainResolve { private readonly DnscryptProxy dnscryptProxy; private readonly DomainSpeedTester speedTester; - private readonly ILogger logger; private readonly TimeSpan speedTestDueTime = TimeSpan.FromSeconds(10d); private readonly TimeSpan speedTestPeriod = TimeSpan.FromMinutes(2d); @@ -22,29 +20,14 @@ namespace FastGithub.DomainResolve /// 域名解析后台服务 /// /// - /// - /// + /// public DomainResolveHostedService( DnscryptProxy dnscryptProxy, - DomainSpeedTester speedTester, - ILogger logger) + DomainSpeedTester speedTester) { this.dnscryptProxy = dnscryptProxy; this.speedTester = speedTester; - this.logger = logger; - } - - /// - /// 停止时 - /// - /// - /// - public override async Task StopAsync(CancellationToken cancellationToken) - { - await this.speedTester.SaveDomainsAsync(); - this.dnscryptProxy.Stop(); - await base.StopAsync(cancellationToken); - } + } /// /// 后台任务 @@ -53,17 +36,9 @@ namespace FastGithub.DomainResolve /// protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - try - { - await this.dnscryptProxy.StartAsync(stoppingToken); - } - catch (Exception ex) - { - this.logger.LogWarning($"{this.dnscryptProxy}启动失败:{ex.Message}"); - } - + await this.dnscryptProxy.StartAsync(stoppingToken); await Task.Delay(this.speedTestDueTime, stoppingToken); - await this.speedTester.LoadDomainsAsync(stoppingToken); + while (stoppingToken.IsCancellationRequested == false) { await this.speedTester.TestSpeedAsync(stoppingToken); diff --git a/FastGithub.DomainResolve/DomainSpeedTester.cs b/FastGithub.DomainResolve/DomainSpeedTester.cs index 743edf0..a300530 100644 --- a/FastGithub.DomainResolve/DomainSpeedTester.cs +++ b/FastGithub.DomainResolve/DomainSpeedTester.cs @@ -1,4 +1,5 @@ using FastGithub.Configuration; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; @@ -13,10 +14,12 @@ namespace FastGithub.DomainResolve /// /// 域名的IP测速服务 /// - sealed class DomainSpeedTester + sealed class DomainSpeedTester : IDisposable { private const string DOMAINS_JSON_FILE = "domains.json"; + private readonly DnsClient dnsClient; + private readonly ILogger logger; private readonly object syncRoot = new(); private readonly Dictionary domainIPAddressHashSet = new(); @@ -25,9 +28,45 @@ namespace FastGithub.DomainResolve /// 域名的IP测速服务 /// /// - public DomainSpeedTester(DnsClient dnsClient) + /// + public DomainSpeedTester( + DnsClient dnsClient, + ILogger logger) { this.dnsClient = dnsClient; + this.logger = logger; + + try + { + this.LoadDomains(); + } + catch (Exception ex) + { + logger.LogWarning($"加载域名数据失败:{ex.Message}"); + } + } + + /// + /// 加载域名数据 + /// + private void LoadDomains() + { + if (File.Exists(DOMAINS_JSON_FILE) == false) + { + return; + } + + var utf8Json = File.ReadAllBytes(DOMAINS_JSON_FILE); + var domains = JsonSerializer.Deserialize(utf8Json); + if (domains == null) + { + return; + } + + foreach (var domain in domains) + { + this.domainIPAddressHashSet.TryAdd(domain, new IPAddressItemHashSet()); + } } /// @@ -60,58 +99,6 @@ namespace FastGithub.DomainResolve } } - /// - /// 加载域名数据 - /// - /// - /// - public async Task LoadDomainsAsync(CancellationToken cancellationToken) - { - if (File.Exists(DOMAINS_JSON_FILE) == false) - { - return; - } - - using var fileStream = File.OpenRead(DOMAINS_JSON_FILE); - var domains = await JsonSerializer.DeserializeAsync(fileStream, cancellationToken: cancellationToken); - if (domains == null) - { - return; - } - - lock (this.syncRoot) - { - foreach (var domain in domains) - { - this.domainIPAddressHashSet.TryAdd(domain, new IPAddressItemHashSet()); - } - } - } - - /// - /// 保存域名数据 - /// - /// - public async Task SaveDomainsAsync() - { - var domains = this.domainIPAddressHashSet.Keys - .Select(item => new DomainPattern(item)) - .OrderBy(item => item) - .Select(item => item.ToString()) - .ToArray(); - - try - { - using var fileStream = File.OpenWrite(DOMAINS_JSON_FILE); - await JsonSerializer.SerializeAsync(fileStream, domains, new JsonSerializerOptions { WriteIndented = true }); - return true; - } - catch (Exception) - { - return false; - } - } - /// /// 进行一轮IP测速 /// @@ -136,5 +123,35 @@ namespace FastGithub.DomainResolve await hashSet.PingAllAsync(); } } + + /// + /// 释放资源 + /// + public void Dispose() + { + try + { + this.SaveDomains(); + } + catch (Exception ex) + { + this.logger.LogWarning($"保存域名数据失败:{ex.Message}"); + } + } + + /// + /// 保存域名 + /// + private void SaveDomains() + { + var domains = this.domainIPAddressHashSet.Keys + .Select(item => new DomainPattern(item)) + .OrderBy(item => item) + .Select(item => item.ToString()) + .ToArray(); + + var utf8Json = JsonSerializer.SerializeToUtf8Bytes(domains, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllBytes(DOMAINS_JSON_FILE, utf8Json); + } } }