using HTEX.ScreenClient.Services; using System.Diagnostics; using System.Management; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using TEAMModelOS.SDK.DI.Device; using Serilog; namespace HTEX.ScreenClient { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); //防止编译后的appsettings.json 文件内容,在重新部署的时候,因为不同的环境导致被覆盖的问题, //所以在正式环境中指定appsettings-prod.json一个本地开发环境不存在的文件,以达到不会被覆盖的问题, //即使在生产环境中未配置appsettings-prod.json 也不影响启动,因为会按照appsettings.json的配置启动 #if !DEBUG builder.Host.ConfigureAppConfiguration((context, config) => { config.SetBasePath(Directory.GetCurrentDirectory()); config.AddJsonFile("appsettings-prod.json", optional: true, reloadOnChange: true); }); #endif builder.WebHost.UseKestrel(options => { // options.ListenAnyIP(CheckOrNewPort(1883), options => {/*options.UseHttps("Crt/iteden.pfx", "iteden");*/ }); options.ListenAnyIP(CheckOrNewPort(5000), options => {/* options.UseHttps("Configs/Crt/iteden.pfx", "iteden"); */}); // Default HTTP pipeline }); //写在端口配置之前,并且在用到的DI之前。否则会导致DI注入失败 Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss.fff zzz} [{Level:u3}] ({ThreadId}) {Message}{NewLine}{Exception}") .WriteTo.File("logs/log-.log", rollingInterval: RollingInterval.Day).CreateLogger(); builder.Host.UseSerilog(); builder.Services.AddControllers(); builder.Services.AddHttpClient(); builder.Services.AddHttpContextAccessor(); builder.Services.AddHostedService(); builder.Services.AddSingleton(); var app = builder.Build(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); } /// /// 检测端口是否可用,如果不可用,则递归调用本方法,直到可用为止 /// /// /// public static int CheckOrNewPort(int port) { if (IsPortAvailable(port)) { return port; } else { return CheckOrNewPort(port + 1); } } /// /// 探测端口是否可用 /// /// /// public static bool IsPortAvailable(int port) { bool isPortAvailable = false; IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); // 本地地址 try { using (Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { // 尝试连接到指定的IP地址和端口 IAsyncResult result = socket.BeginConnect(ipAddress, port, null, null); // 等待连接尝试完成(这里简单地使用Socket的ConnectTimeout,但更常见的做法是使用超时等待或异步回调) bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1), true); if (success) { // 如果连接成功,则端口被占用 socket.EndConnect(result); isPortAvailable = false; // 可选:如果需要,可以在这里关闭连接 //socket.Shutdown(SocketShutdown.Both); //socket.Close(); } else { isPortAvailable = true; } } } catch (SocketException ex) { Console.WriteLine($"{ex.Message},{ex.SocketErrorCode}"); // 如果错误代码为10048,则表示地址已被使用 if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse) { isPortAvailable = false; } if (ex.SocketErrorCode==SocketError.ConnectionRefused) { isPortAvailable=true; } } catch (Exception ex) { Console.WriteLine(ex.Message); isPortAvailable = false; } return isPortAvailable; } } }