using FastGithub.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Diagnostics; using System.Linq; using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace FastGithub { /// /// app后台服务 /// sealed class AppHostedService : BackgroundService { private readonly IHost host; private readonly IOptions appOptions; private readonly IOptions fastGithubOptions; private readonly ILogger logger; public AppHostedService( IHost host, IOptions appOptions, IOptions fastGithubOptions, ILogger logger) { this.host = host; this.appOptions = appOptions; this.fastGithubOptions = fastGithubOptions; this.logger = logger; } /// /// 启动完成 /// /// /// public override Task StartAsync(CancellationToken cancellationToken) { var version = ProductionVersion.Current; this.logger.LogInformation($"{nameof(FastGithub)}启动完成,当前版本为v{version},访问 https://github.com/dotnetcore/fastgithub 关注新版本"); return base.StartAsync(cancellationToken); } /// /// 后台任务 /// /// /// protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(TimeSpan.FromSeconds(1d), stoppingToken); await this.CheckFastGithubProxyAsync(stoppingToken); await this.WaitForParentProcessExitAsync(stoppingToken); } /// /// 检测fastgithub代理设置 /// /// /// private async Task CheckFastGithubProxyAsync(CancellationToken cancellationToken) { if (OperatingSystem.IsWindows() == false) { if (await this.UseFastGithubProxyAsync() == false) { var httpProxyPort = this.fastGithubOptions.Value.HttpProxyPort; this.logger.LogWarning($"请设置系统自动代理为http://{IPAddress.Loopback}:{httpProxyPort},或手动代理http/https为{IPAddress.Loopback}:{httpProxyPort}"); } } } /// /// 应用fastgithub代理 /// /// /// /// private async Task UseFastGithubProxyAsync() { var systemProxy = HttpClient.DefaultProxy; if (systemProxy == null) { return false; } var domain = this.fastGithubOptions.Value.DomainConfigs.Keys.FirstOrDefault(); if (domain == null) { return true; } var destination = new Uri($"https://{domain.Replace('*', 'a')}"); var proxyServer = systemProxy.GetProxy(destination); if (proxyServer == null) { return false; } var httpProxyPort = this.fastGithubOptions.Value.HttpProxyPort; if (proxyServer.Port != httpProxyPort) { return false; } if (IPAddress.TryParse(proxyServer.Host, out var address)) { return address.Equals(IPAddress.Loopback); } try { var addresses = await Dns.GetHostAddressesAsync(proxyServer.Host); return addresses.Contains(IPAddress.Loopback); } catch (Exception) { return false; } } /// /// 等待父进程退出 /// /// /// private async Task WaitForParentProcessExitAsync(CancellationToken cancellationToken) { var parentId = this.appOptions.Value.ParentProcessId; if (parentId <= 0) { return; } try { Process.GetProcessById(parentId).WaitForExit(); } catch (Exception ex) { this.logger.LogError(ex, $"获取进程{parentId}异常"); } finally { this.logger.LogInformation($"正在主动关闭,因为父进程已退出"); await this.host.StopAsync(cancellationToken); } } } }