forked from shiftwinting/FastGithub
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
272 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using Microsoft.Extensions.Hosting; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace FastGithub.DomainResolve | ||
{ | ||
/// <summary> | ||
/// 域名的IP测速后台服务 | ||
/// </summary> | ||
sealed class DomainSpeedTestHostedService : BackgroundService | ||
{ | ||
private readonly DomainSpeedTestService speedTestService; | ||
private readonly TimeSpan testDueTime = TimeSpan.FromMinutes(1d); | ||
|
||
/// <summary> | ||
/// 域名的IP测速后台服务 | ||
/// </summary> | ||
/// <param name="speedTestService"></param> | ||
public DomainSpeedTestHostedService(DomainSpeedTestService speedTestService) | ||
{ | ||
this.speedTestService = speedTestService; | ||
} | ||
|
||
/// <summary> | ||
/// 启动时 | ||
/// </summary> | ||
/// <param name="cancellationToken"></param> | ||
/// <returns></returns> | ||
public override async Task StartAsync(CancellationToken cancellationToken) | ||
{ | ||
await this.speedTestService.LoadDataAsync(cancellationToken); | ||
await base.StartAsync(cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// 停止时 | ||
/// </summary> | ||
/// <param name="cancellationToken"></param> | ||
/// <returns></returns> | ||
public override async Task StopAsync(CancellationToken cancellationToken) | ||
{ | ||
await this.speedTestService.SaveDataAsync(); | ||
await base.StopAsync(cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
/// 后台测速 | ||
/// </summary> | ||
/// <param name="stoppingToken"></param> | ||
/// <returns></returns> | ||
protected override async Task ExecuteAsync(CancellationToken stoppingToken) | ||
{ | ||
while (stoppingToken.IsCancellationRequested == false) | ||
{ | ||
await this.speedTestService.TestSpeedAsync(stoppingToken); | ||
await Task.Delay(this.testDueTime, stoppingToken); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Text.Json; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
namespace FastGithub.DomainResolve | ||
{ | ||
/// <summary> | ||
/// 域名的IP测速服务 | ||
/// </summary> | ||
sealed class DomainSpeedTestService | ||
{ | ||
private const string DATA_FILE = "domains.json"; | ||
private readonly DnsClient dnsClient; | ||
|
||
private readonly object syncRoot = new(); | ||
private readonly Dictionary<string, IPAddressItemHashSet> domainIPAddressHashSet = new(); | ||
|
||
/// <summary> | ||
/// 域名的IP测速服务 | ||
/// </summary> | ||
/// <param name="dnsClient"></param> | ||
public DomainSpeedTestService(DnsClient dnsClient) | ||
{ | ||
this.dnsClient = dnsClient; | ||
} | ||
|
||
/// <summary> | ||
/// 添加要测速的域名 | ||
/// </summary> | ||
/// <param name="domain"></param> | ||
/// <returns></returns> | ||
public bool Add(string domain) | ||
{ | ||
lock (this.syncRoot) | ||
{ | ||
return this.domainIPAddressHashSet.TryAdd(domain, new IPAddressItemHashSet()); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// 获取测试后排序的IP | ||
/// </summary> | ||
/// <param name="domain"></param> | ||
/// <returns></returns> | ||
public IPAddress[] GetIPAddresses(string domain) | ||
{ | ||
lock (this.syncRoot) | ||
{ | ||
if (this.domainIPAddressHashSet.TryGetValue(domain, out var hashSet) && hashSet.Count > 0) | ||
{ | ||
return hashSet.ToArray().OrderBy(item => item.PingElapsed).Select(item => item.Address).ToArray(); | ||
} | ||
return Array.Empty<IPAddress>(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// 加载数据 | ||
/// </summary> | ||
/// <param name="cancellationToken"></param> | ||
/// <returns></returns> | ||
public async Task LoadDataAsync(CancellationToken cancellationToken) | ||
{ | ||
if (File.Exists(DATA_FILE) == false) | ||
{ | ||
return; | ||
} | ||
|
||
var fileStream = File.OpenRead(DATA_FILE); | ||
var domains = await JsonSerializer.DeserializeAsync<string[]>(fileStream, cancellationToken: cancellationToken); | ||
if (domains == null) | ||
{ | ||
return; | ||
} | ||
|
||
lock (this.syncRoot) | ||
{ | ||
foreach (var domain in domains) | ||
{ | ||
this.domainIPAddressHashSet.TryAdd(domain, new IPAddressItemHashSet()); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// 保存数据 | ||
/// </summary> | ||
/// <returns></returns> | ||
public async Task SaveDataAsync() | ||
{ | ||
var domains = this.domainIPAddressHashSet.Keys.ToArray(); | ||
using var fileStream = File.OpenWrite(DATA_FILE); | ||
await JsonSerializer.SerializeAsync(fileStream, domains); | ||
} | ||
|
||
/// <summary> | ||
/// 进行一轮IP测速 | ||
/// </summary> | ||
/// <param name="cancellationToken"></param> | ||
/// <returns></returns> | ||
public async Task TestSpeedAsync(CancellationToken cancellationToken) | ||
{ | ||
KeyValuePair<string, IPAddressItemHashSet>[] keyValues; | ||
lock (this.syncRoot) | ||
{ | ||
keyValues = this.domainIPAddressHashSet.ToArray(); | ||
} | ||
|
||
foreach (var keyValue in keyValues) | ||
{ | ||
var domain = keyValue.Key; | ||
var hashSet = keyValue.Value; | ||
await foreach (var address in this.dnsClient.ResolveAsync(domain, cancellationToken)) | ||
{ | ||
hashSet.Add(new IPAddressItem(address)); | ||
} | ||
await hashSet.PingAllAsync(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.