Program.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using HTEX.ScreenClient.Services;
  2. using System.Diagnostics;
  3. using System.Management;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Runtime.InteropServices;
  7. using System.Text.RegularExpressions;
  8. using TEAMModelOS.SDK.DI.Device;
  9. using Serilog;
  10. namespace HTEX.ScreenClient
  11. {
  12. public class Program
  13. {
  14. public static void Main(string[] args)
  15. {
  16. var builder = WebApplication.CreateBuilder(args);
  17. //防止编译后的appsettings.json 文件内容,在重新部署的时候,因为不同的环境导致被覆盖的问题,
  18. //所以在正式环境中指定appsettings-prod.json一个本地开发环境不存在的文件,以达到不会被覆盖的问题,
  19. //即使在生产环境中未配置appsettings-prod.json 也不影响启动,因为会按照appsettings.json的配置启动
  20. #if !DEBUG
  21. builder.Host.ConfigureAppConfiguration((context, config) => {
  22. config.SetBasePath(Directory.GetCurrentDirectory());
  23. config.AddJsonFile("appsettings-prod.json", optional: true, reloadOnChange: true);
  24. });
  25. #endif
  26. builder.WebHost.UseKestrel(options =>
  27. {
  28. // options.ListenAnyIP(CheckOrNewPort(1883), options => {/*options.UseHttps("Crt/iteden.pfx", "iteden");*/ });
  29. options.ListenAnyIP(CheckOrNewPort(5000), options => {/* options.UseHttps("Configs/Crt/iteden.pfx", "iteden"); */}); // Default HTTP pipeline
  30. });
  31. //写在端口配置之前,并且在用到的DI之前。否则会导致DI注入失败
  32. Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss.fff zzz} [{Level:u3}] ({ThreadId}) {Message}{NewLine}{Exception}")
  33. .WriteTo.File("logs/log-.log", rollingInterval: RollingInterval.Day).CreateLogger();
  34. builder.Host.UseSerilog();
  35. builder.Services.AddControllers();
  36. builder.Services.AddHttpClient();
  37. builder.Services.AddHttpContextAccessor();
  38. builder.Services.AddHostedService<SignalRScreenClientHub>();
  39. builder.Services.AddSingleton<CoreDevice>();
  40. var app = builder.Build();
  41. app.UseHttpsRedirection();
  42. app.UseAuthorization();
  43. app.MapControllers();
  44. app.Run();
  45. }
  46. /// <summary>
  47. /// 检测端口是否可用,如果不可用,则递归调用本方法,直到可用为止
  48. /// </summary>
  49. /// <param name="port"></param>
  50. /// <returns></returns>
  51. public static int CheckOrNewPort(int port)
  52. {
  53. if (IsPortAvailable(port))
  54. {
  55. return port;
  56. }
  57. else
  58. {
  59. return CheckOrNewPort(port + 1);
  60. }
  61. }
  62. /// <summary>
  63. /// 探测端口是否可用
  64. /// </summary>
  65. /// <param name="port"></param>
  66. /// <returns></returns>
  67. public static bool IsPortAvailable(int port)
  68. {
  69. bool isPortAvailable = false;
  70. IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); // 本地地址
  71. try
  72. {
  73. using (Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
  74. {
  75. // 尝试连接到指定的IP地址和端口
  76. IAsyncResult result = socket.BeginConnect(ipAddress, port, null, null);
  77. // 等待连接尝试完成(这里简单地使用Socket的ConnectTimeout,但更常见的做法是使用超时等待或异步回调)
  78. bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1), true);
  79. if (success)
  80. {
  81. // 如果连接成功,则端口被占用
  82. socket.EndConnect(result);
  83. isPortAvailable = false;
  84. // 可选:如果需要,可以在这里关闭连接
  85. //socket.Shutdown(SocketShutdown.Both);
  86. //socket.Close();
  87. }
  88. else
  89. {
  90. isPortAvailable = true;
  91. }
  92. }
  93. }
  94. catch (SocketException ex)
  95. {
  96. Console.WriteLine($"{ex.Message},{ex.SocketErrorCode}");
  97. // 如果错误代码为10048,则表示地址已被使用
  98. if (ex.SocketErrorCode == SocketError.AddressAlreadyInUse)
  99. {
  100. isPortAvailable = false;
  101. }
  102. if (ex.SocketErrorCode==SocketError.ConnectionRefused)
  103. {
  104. isPortAvailable=true;
  105. }
  106. }
  107. catch (Exception ex)
  108. {
  109. Console.WriteLine(ex.Message);
  110. isPortAvailable = false;
  111. }
  112. return isPortAvailable;
  113. }
  114. }
  115. }