using DotNetty.Codecs.Http;
using DotNetty.Transport.Bootstrapping;
using DotNetty.Transport.Channels;
using DotNetty.Transport.Libuv;
using JT809.DotNetty.Core.Configurations;
using JT809.DotNetty.Core.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
{
///
/// JT809 集成一个webapi服务
///
internal class JT809MainWebAPIServerHost : IHostedService
{
private readonly IServiceProvider serviceProvider;
private readonly ILogger logger;
private DispatcherEventLoopGroup bossGroup;
private WorkerEventLoopGroup workerGroup;
private IChannel bootstrapChannel;
private readonly JT809SuperiorPlatformOptions configuration;
public JT809MainWebAPIServerHost(
IServiceProvider provider,
IOptions jT809SuperiorPlatformOptionsAccessor,
ILoggerFactory loggerFactory)
{
serviceProvider = provider;
configuration = jT809SuperiorPlatformOptionsAccessor.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_jt809webapihandler", scope.ServiceProvider.GetRequiredService());
}
}));
logger.LogInformation($"JT809 Superior 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);
}
}
}