using System.Net; using Microsoft.AspNetCore.Connections; namespace PCC.Common.Networking; public class KestrelTcpServer(string ip, int port, ConnectionDelegate connectionHandler, ILogger logger) { private IHost? _host; public async Task StartAsync(CancellationToken cancellationToken = default) { if (_host != null) { throw new InvalidOperationException("Server is already running."); } _host = Host.CreateDefaultBuilder() .ConfigureLogging(logging => { logging.ClearProviders(); // 清除默认日志提供者(可选) logging.AddProvider(new LoggerProvider(logger)); // 添加自定义日志提供者 }) .ConfigureWebHostDefaults(webBuilder => { webBuilder .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. .Configure(app => { // 防止启动时报错 No application configured // 没用🙄 无法取消日志 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 //app.Use(async (HttpContext context, RequestDelegate next) => context.Response.WriteAsync("Hello from Kestrel!")); }) .UseKestrel(kop => { kop.Listen(IPAddress.Parse(ip), port, lop => { lop.Use(async (ConnectionContext context, ConnectionDelegate next) => await connectionHandler(context)); }); }); }) .Build(); await _host.StartAsync(cancellationToken); } public async Task StopAsync(CancellationToken cancellationToken = default) { if (_host == null) throw new InvalidOperationException("Server is not running."); await _host.StopAsync(cancellationToken); Console.WriteLine("Server stopped."); _host = null; } // 示例自定义日志提供者(可根据需求自定义实现) private class LoggerProvider(ILogger logger) : ILoggerProvider { public ILogger CreateLogger(string categoryName) { return new CustomLogger(logger, categoryName); } public void Dispose() { // 处理必要的清理 这里没有 } } private class CustomLogger(ILogger logger, string categoryName) : ILogger { public IDisposable? BeginScope(TState state) where TState : notnull => logger.BeginScope(state); public bool IsEnabled(LogLevel logLevel) => logger.IsEnabled(logLevel); public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) { if (formatter == null) return; logger.Log(logLevel, eventId, categoryName + ": " + formatter(state, exception), exception); } } }