using DotNetty.Codecs.Http; using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Libuv; using JT808.DotNetty.Configurations; using JT808.DotNetty.Handlers; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Net; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace JT808.DotNetty { /// /// 集成一个webapi服务 /// internal class JT808WebAPIServerHost : IHostedService { private readonly IServiceProvider serviceProvider; private readonly JT808Configuration configuration; private readonly ILogger logger; private DispatcherEventLoopGroup bossGroup; private WorkerEventLoopGroup workerGroup; private IChannel bootstrapChannel; public JT808WebAPIServerHost( IServiceProvider provider, ILoggerFactory loggerFactory, IOptions jT808ConfigurationAccessor) { serviceProvider = provider; configuration = jT808ConfigurationAccessor.Value; logger = loggerFactory.CreateLogger(); } public Task StartAsync(CancellationToken cancellationToken) { bossGroup = new DispatcherEventLoopGroup(); workerGroup = new WorkerEventLoopGroup(bossGroup, 1); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.Group(bossGroup, workerGroup); bootstrap.Channel(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true) .ChildOption(ChannelOption.SoReuseaddr, true); } bootstrap .Option(ChannelOption.SoBacklog, 8192) .ChildHandler(new ActionChannelInitializer(channel => { IChannelPipeline pipeline = channel.Pipeline; using (var scope = serviceProvider.CreateScope()) { pipeline.AddLast("http_encoder", new HttpResponseEncoder()); pipeline.AddLast("http_decoder", new HttpRequestDecoder(4096, 8192, 8192, false)); //将多个消息转换为单一的request或者response对象 =>IFullHttpRequest pipeline.AddLast("http_aggregator", new HttpObjectAggregator(65536)); pipeline.AddLast("http_jt808webapihandler", scope.ServiceProvider.GetRequiredService()); } })); logger.LogInformation($"WebAPI Server start at {IPAddress.Any}:{configuration.WebAPIPort}."); return bootstrap.BindAsync(configuration.WebAPIPort).ContinueWith(i => bootstrapChannel = i.Result); } public async Task StopAsync(CancellationToken cancellationToken) { await bootstrapChannel.CloseAsync(); var quietPeriod = configuration.QuietPeriodTimeSpan; var shutdownTimeout = configuration.ShutdownTimeoutTimeSpan; await workerGroup.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); await bossGroup.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); } } }