KestrelTcpServer.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using System.Net;
  2. using Microsoft.AspNetCore.Connections;
  3. namespace PCC.Common.Networking;
  4. public class KestrelTcpServer(string ip, int port, ConnectionDelegate connectionHandler, ILogger<KestrelTcpServer> logger)
  5. {
  6. private IHost? _host;
  7. public async Task StartAsync(CancellationToken cancellationToken = default)
  8. {
  9. if (_host != null)
  10. {
  11. throw new InvalidOperationException("Server is already running.");
  12. }
  13. _host = Host.CreateDefaultBuilder()
  14. .ConfigureLogging(logging =>
  15. {
  16. logging.ClearProviders(); // 清除默认日志提供者(可选)
  17. logging.AddProvider(new LoggerProvider(logger)); // 添加自定义日志提供者
  18. })
  19. .ConfigureWebHostDefaults(webBuilder =>
  20. {
  21. webBuilder
  22. .UseUrls() //消除警告 Microsoft.AspNetCore.Server.Kestrel[0] Overriding address(es) 'https://localhost:5001/, http://localhost:5000/'. Binding to endpoints defined via IConfiguration and/or UseKestrel() instead.
  23. .Configure(app =>
  24. {
  25. // 防止启动时报错 No application configured
  26. // 没用🙄 无法取消日志 No action descriptors found. This may indicate an incorrectly configured application or missing application parts. To learn more, visit https://aka.ms/aspnet/mvc/app-parts
  27. //app.Use(async (HttpContext context, RequestDelegate next) => context.Response.WriteAsync("Hello from Kestrel!"));
  28. })
  29. .UseKestrel(kop =>
  30. {
  31. kop.Listen(IPAddress.Parse(ip), port, lop =>
  32. {
  33. lop.Use(async (ConnectionContext context, ConnectionDelegate next) => await connectionHandler(context));
  34. });
  35. });
  36. })
  37. .Build();
  38. await _host.StartAsync(cancellationToken);
  39. }
  40. public async Task StopAsync(CancellationToken cancellationToken = default)
  41. {
  42. if (_host == null)
  43. throw new InvalidOperationException("Server is not running.");
  44. await _host.StopAsync(cancellationToken);
  45. Console.WriteLine("Server stopped.");
  46. _host = null;
  47. }
  48. // 示例自定义日志提供者(可根据需求自定义实现)
  49. private class LoggerProvider(ILogger logger) : ILoggerProvider
  50. {
  51. public ILogger CreateLogger(string categoryName)
  52. {
  53. return new CustomLogger(logger, categoryName);
  54. }
  55. public void Dispose()
  56. {
  57. // 处理必要的清理 这里没有
  58. }
  59. }
  60. private class CustomLogger(ILogger logger, string categoryName) : ILogger
  61. {
  62. public IDisposable? BeginScope<TState>(TState state) where TState : notnull => logger.BeginScope(state);
  63. public bool IsEnabled(LogLevel logLevel) => logger.IsEnabled(logLevel);
  64. public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
  65. {
  66. if (formatter == null) return;
  67. logger.Log(logLevel, eventId, categoryName + ": " + formatter(state, exception), exception);
  68. }
  69. }
  70. }