使用远程meta信息

This commit is contained in:
陈国伟 2021-06-11 14:02:02 +08:00
parent 553b7f8c07
commit a1ae1bbeca
9 changed files with 115 additions and 19 deletions

View File

@ -8,12 +8,13 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="meta.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

View File

@ -1,11 +1,10 @@
using FastGithub.Middlewares;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@ -14,10 +13,12 @@ namespace FastGithub
sealed class GithubHostedService : BackgroundService
{
private readonly GithubDelegate githubDelegate;
private readonly IServiceScopeFactory serviceScopeFactory;
private readonly ILogger<GithubHostedService> logger;
public GithubHostedService(
IServiceProvider appServiceProvider,
IServiceScopeFactory serviceScopeFactory,
ILogger<GithubHostedService> logger)
{
this.githubDelegate = new GithubBuilder(appServiceProvider, ctx => Task.CompletedTask)
@ -26,13 +27,16 @@ namespace FastGithub
.Use<HttpTestMiddleware>()
.Build();
this.serviceScopeFactory = serviceScopeFactory;
this.logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var stream = File.OpenRead("meta.json");
var meta = await JsonSerializer.DeserializeAsync<Meta>(stream, cancellationToken: stoppingToken);
using var scope = this.serviceScopeFactory.CreateScope();
var metaService = scope.ServiceProvider.GetRequiredService<MetaService>();
var meta = await metaService.GetMetaAsync();
if (meta != null)
{
@ -49,8 +53,10 @@ namespace FastGithub
this.logger.LogInformation($"{context.Address} {context.HttpElapsed}");
}
}
this.logger.LogInformation("扫描结束");
}
}
private IEnumerable<Task> GetScanTasks(Meta meta, IList<GithubContext> contexts)
{

View File

@ -0,0 +1,15 @@
using System;
namespace FastGithub
{
class GithubOptions
{
public Uri MetaUri { get; set; } = new Uri("https://gitee.com/jiulang/fast-github/raw/master/FastGithub/meta.json");
public int Concurrent { get; set; } = 50;
public TimeSpan PortScanTimeout { get; set; } = TimeSpan.FromSeconds(1d);
public TimeSpan HttpTestTimeout { get; set; } = TimeSpan.FromSeconds(5d);
}
}

40
FastGithub/MetaService.cs Normal file
View File

@ -0,0 +1,40 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace FastGithub
{
sealed class MetaService
{
private readonly IHttpClientFactory httpClientFactory;
private readonly IOptionsMonitor<GithubOptions> options;
private readonly ILogger<MetaService> logger;
public MetaService(
IHttpClientFactory httpClientFactory,
IOptionsMonitor<GithubOptions> options,
ILogger<MetaService> logger)
{
this.httpClientFactory = httpClientFactory;
this.options = options;
this.logger = logger;
}
public async Task<Meta?> GetMetaAsync()
{
try
{
var httpClient = this.httpClientFactory.CreateClient();
return await httpClient.GetFromJsonAsync<Meta>(this.options.CurrentValue.MetaUri);
}
catch (Exception ex)
{
this.logger.LogError(ex, "获取meta.json文件失败");
return default;
}
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.Options;
using System;
using System.Threading;
using System.Threading.Tasks;
@ -6,7 +7,12 @@ namespace FastGithub.Middlewares
{
sealed class ConcurrentMiddleware : IGithubMiddleware
{
private readonly SemaphoreSlim semaphoreSlim = new(50);
private readonly SemaphoreSlim semaphoreSlim;
public ConcurrentMiddleware(IOptions<GithubOptions> options)
{
this.semaphoreSlim = new SemaphoreSlim(options.Value.Concurrent);
}
public async Task InvokeAsync(GithubContext context, Func<Task> next)
{

View File

@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net.Http;
using System.Threading;
@ -8,11 +9,14 @@ namespace FastGithub.Middlewares
{
sealed class HttpTestMiddleware : IGithubMiddleware
{
private readonly TimeSpan timeout = TimeSpan.FromSeconds(5d);
private readonly IOptionsMonitor<GithubOptions> options;
private readonly ILogger<HttpTestMiddleware> logger;
public HttpTestMiddleware(ILogger<HttpTestMiddleware> logger)
public HttpTestMiddleware(
IOptionsMonitor<GithubOptions> options,
ILogger<HttpTestMiddleware> logger)
{
this.options = options;
this.logger = logger;
}
@ -33,11 +37,11 @@ namespace FastGithub.Middlewares
});
var startTime = DateTime.Now;
using var cancellationTokenSource = new CancellationTokenSource(this.timeout);
using var cancellationTokenSource = new CancellationTokenSource(this.options.CurrentValue.HttpTestTimeout);
var response = await httpClient.SendAsync(request, cancellationTokenSource.Token);
var media = response.EnsureSuccessStatusCode().Content.Headers.ContentType?.MediaType;
if (string.Equals(media, "application/manifest+json"))
if (string.Equals(media, "application/manifest+json", StringComparison.OrdinalIgnoreCase))
{
context.HttpElapsed = DateTime.Now.Subtract(startTime);
await next();

View File

@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net.Sockets;
using System.Threading;
@ -8,27 +9,31 @@ namespace FastGithub.Middlewares
{
sealed class PortScanMiddleware : IGithubMiddleware
{
private readonly TimeSpan timeout = TimeSpan.FromSeconds(1d);
private const int PORT = 443;
private readonly IOptionsMonitor<GithubOptions> options;
private readonly ILogger<PortScanMiddleware> logger;
public PortScanMiddleware(ILogger<PortScanMiddleware> logger)
public PortScanMiddleware(
IOptionsMonitor<GithubOptions> options,
ILogger<PortScanMiddleware> logger)
{
this.options = options;
this.logger = logger;
}
public async Task InvokeAsync(GithubContext context, Func<Task> next)
{
try
{
{
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
using var cancellationTokenSource = new CancellationTokenSource(this.timeout);
await socket.ConnectAsync(context.Address, 443, cancellationTokenSource.Token);
using var cancellationTokenSource = new CancellationTokenSource(this.options.CurrentValue.PortScanTimeout);
await socket.ConnectAsync(context.Address, PORT, cancellationTokenSource.Token);
await next();
}
catch (Exception)
{
this.logger.LogInformation($"{context.Address}的443端口未开放");
this.logger.LogInformation($"{context.Address}的{PORT}端口未开放");
}
}
}

View File

@ -27,6 +27,9 @@ namespace FastGithub
.ConfigureServices((ctx, services) =>
{
services
.Configure<GithubOptions>(ctx.Configuration.GetSection("Github"))
.AddHttpClient()
.AddTransient<MetaService>()
.AddSingleton<PortScanMiddleware>()
.AddSingleton<HttpTestMiddleware>()
.AddSingleton<ConcurrentMiddleware>()

View File

@ -0,0 +1,16 @@
{
"Github": {
"MetaUri": "https://gitee.com/jiulang/fast-github/raw/master/FastGithub/meta.json", // ipuri
"Concurrent": 50, //
"PortScanTimeout": "00:00:01", //
"HttpTestTimeout": "00:00:05" // http
},
"Logging": {
"LogLevel": {
"Default": "Information",
"System": "Warning",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}