123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- using Microsoft.Extensions.Logging;
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Runtime.CompilerServices;
- using System.Threading;
- using System.Threading.Tasks;
- namespace FastGithub.DomainResolve
- {
- /// <summary>
- /// 域名解析器
- /// </summary>
- sealed class DomainResolver : IDomainResolver
- {
- private readonly DnsClient dnsClient;
- private readonly DomainPersistence persistence;
- private readonly IPAddressService addressService;
- private readonly ILogger<DomainResolver> logger;
- private readonly ConcurrentDictionary<DnsEndPoint, IPAddress[]> dnsEndPointAddress = new();
- /// <summary>
- /// 域名解析器
- /// </summary>
- /// <param name="dnsClient"></param>
- /// <param name="persistence"></param>
- /// <param name="addressService"></param>
- /// <param name="logger"></param>
- public DomainResolver(
- DnsClient dnsClient,
- DomainPersistence persistence,
- IPAddressService addressService,
- ILogger<DomainResolver> logger)
- {
- this.dnsClient = dnsClient;
- this.persistence = persistence;
- this.addressService = addressService;
- this.logger = logger;
- foreach (var endPoint in persistence.ReadDnsEndPoints())
- {
- this.dnsEndPointAddress.TryAdd(endPoint, Array.Empty<IPAddress>());
- }
- }
- /// <summary>
- /// 解析域名
- /// </summary>
- /// <param name="endPoint">节点</param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public async IAsyncEnumerable<IPAddress> ResolveAsync(DnsEndPoint endPoint, [EnumeratorCancellation] CancellationToken cancellationToken)
- {
- if (this.dnsEndPointAddress.TryGetValue(endPoint, out var addresses) && addresses.Length > 0)
- {
- foreach (var address in addresses)
- {
- yield return address;
- }
- }
- else
- {
- if (this.dnsEndPointAddress.TryAdd(endPoint, Array.Empty<IPAddress>()))
- {
- await this.persistence.WriteDnsEndPointsAsync(this.dnsEndPointAddress.Keys, cancellationToken);
- }
- await foreach (var adddress in this.dnsClient.ResolveAsync(endPoint, fastSort: true, cancellationToken))
- {
- yield return adddress;
- }
- }
- }
- /// <summary>
- /// 对所有节点进行测速
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- public async Task TestAllEndPointsAsync(CancellationToken cancellationToken)
- {
- foreach (var keyValue in this.dnsEndPointAddress)
- {
- var dnsEndPoint = keyValue.Key;
- var oldAddresses = keyValue.Value;
- var newAddresses = await this.addressService.GetAddressesAsync(dnsEndPoint, oldAddresses, cancellationToken);
- this.dnsEndPointAddress[dnsEndPoint] = newAddresses;
- var oldSegmentum = oldAddresses.Take(5);
- var newSegmentum = newAddresses.Take(5);
- if (oldSegmentum.SequenceEqual(newSegmentum) == false)
- {
- var addressArray = string.Join(", ", newSegmentum.Select(item => item.ToString()));
- this.logger.LogInformation($"{dnsEndPoint.Host}:{dnsEndPoint.Port}->[{addressArray}]");
- }
- }
- }
- }
- }
|