using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.Extensions.Configuration; using System.Net; using System.Net.NetworkInformation; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using System.Web; using TEAMModelOS.SDK; using TEAMModelOS.SDK.Extension; namespace HTEX.ScreenClient.Services { public class SignalRClientHub : BackgroundService, IDisposable { private readonly IConfiguration _configuration; private readonly ILogger _logger; private readonly IHttpClientFactory _httpClientFactory; private readonly IServiceProvider _services; private IEnumerable? _url = new List(); public SignalRClientHub(IConfiguration configuration,ILogger logger,IHttpClientFactory httpClientFactory, IServiceProvider services,IHostApplicationLifetime lifetime) { _configuration=configuration; _logger=logger; _httpClientFactory=httpClientFactory; _services=services; lifetime.ApplicationStarted.Register(() => { var server = _services.GetService(); _url = server?.Features.Get()?.Addresses; }); } private List messages = new List(); protected async override Task ExecuteAsync(CancellationToken stoppingToken) { var device = await GetClientInfo(); string hashData = $"{device.name}-{device.remote}-{device.port}-{device.os}-{string.Join(",",device.networks.Select(x=>$"{x.mac}-{x.ip}"))}"; string clientid = ShaHashHelper.GetSHA256(hashData); string? CenterUrl = _configuration.GetSection("ScreenClient:CenterUrl").Value; string? ScreenUrl = _configuration.GetSection("ScreenClient:ScreenUrl").Value; long Timeout = _configuration.GetValue("ScreenClient:Timeout"); long Delay = _configuration.GetValue("ScreenClient:Delay"); device.timeout = Timeout; device.delay = Delay; device.screenUrl = ScreenUrl; HubConnection hubConnection = new HubConnectionBuilder() .WithUrl($"{CenterUrl}/signalr/screen?grant_type=bookjs_api&clientid={clientid}&device={HttpUtility.UrlEncode(device.ToJsonString(),Encoding.Unicode)}") //only one slash .WithAutomaticReconnect() .ConfigureLogging(logging => { logging.SetMinimumLevel(LogLevel.Information); logging.AddConsole(); }) .Build(); hubConnection.On("ReceiveConnection", ( message) => { var encodedMsg = $" {message}"; _logger.LogInformation($"连接成功:{message.ToJsonString()}"); messages.Add(encodedMsg); }); hubConnection.On("ReceiveMessage", (message) => { var encodedMsg = $"{message}"; messages.Add(encodedMsg); }); await hubConnection.StartAsync(); } public async Task GetClientInfo() { string hostName =$"{Environment.UserName}-{Dns.GetHostName()}" ; string os = RuntimeInformation.OSDescription; //获取当前客户端的服务端口 var _httpClient = _httpClientFactory.CreateClient(); ClientDevice device = new ClientDevice { name =hostName, os= os }; HttpResponseMessage message = await _httpClient.PostAsJsonAsync("https://www.teammodel.cn/core/system-info", new { }); if (message.IsSuccessStatusCode) { JsonNode? json = JsonSerializer.Deserialize(await message.Content.ReadAsStringAsync()); var ip = json?["ip"]; var region = json?["region"]; _logger.LogInformation($"远程地址:{ip}"); _logger.LogInformation($"所属地区:{region}"); device.remote=ip?.ToString(); device.region=region?.ToString(); } _logger.LogInformation($"计算机名:{hostName}"); _logger.LogInformation($"系统名称:{RuntimeInformation.OSDescription}"); var nics = NetworkInterface.GetAllNetworkInterfaces(); foreach (var nic in nics) { if (nic.OperationalStatus == OperationalStatus.Up) { var mac = nic.GetPhysicalAddress().ToString(); var properties = nic.GetIPProperties(); var unicastAddresses = properties.UnicastAddresses; foreach (var unicast in unicastAddresses) { if (unicast.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { var ip = unicast.Address.ToString(); Network network= new Network() { mac=mac, ip=ip }; if (!string.IsNullOrWhiteSpace(mac.ToString())) { device.networks.Add(network); _logger.LogInformation($"网卡地址: {mac}"); _logger.LogInformation($"内网地址: {ip}"); } } } } } if (_url!=null) { List ports = new List(); foreach (var url in _url) { Uri uri = new Uri(url); ports.Add(uri.Port); } device.port= string.Join(",", ports); _logger.LogInformation($"占用端口: {device.port}"); } return device ; } } }