using DotNetty.Transport.Bootstrapping; using DotNetty.Transport.Channels; using DotNetty.Transport.Channels.Sockets; using JT808.DotNetty.Core.Codecs; using JT808.DotNetty.Core.Configurations; using JT808.DotNetty.Udp.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.Udp { /// /// JT808 Udp网关服务 /// internal class JT808UdpServerHost : IHostedService { private readonly IServiceProvider serviceProvider; private readonly JT808Configuration configuration; private readonly ILogger logger; private MultithreadEventLoopGroup group; private IChannel bootstrapChannel; public JT808UdpServerHost( IServiceProvider provider, ILoggerFactory loggerFactory, IOptions jT808ConfigurationAccessor) { serviceProvider = provider; configuration = jT808ConfigurationAccessor.Value; logger=loggerFactory.CreateLogger(); } public Task StartAsync(CancellationToken cancellationToken) { group = new MultithreadEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.Group(group); bootstrap.Channel(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { bootstrap .Option(ChannelOption.SoReuseport, true); } bootstrap .Option(ChannelOption.SoBroadcast, true) .Handler(new ActionChannelInitializer(channel => { IChannelPipeline pipeline = channel.Pipeline; using (var scope = serviceProvider.CreateScope()) { pipeline.AddLast("jt808UdpDecoder", scope.ServiceProvider.GetRequiredService()); pipeline.AddLast("jt808UdpService", scope.ServiceProvider.GetRequiredService()); } })); logger.LogInformation($"JT808 Udp Server start at {IPAddress.Any}:{configuration.UdpPort}."); return bootstrap.BindAsync(configuration.UdpPort) .ContinueWith(i => bootstrapChannel = i.Result); } public async Task StopAsync(CancellationToken cancellationToken) { await bootstrapChannel.CloseAsync(); var quietPeriod = configuration.QuietPeriodTimeSpan; var shutdownTimeout = configuration.ShutdownTimeoutTimeSpan; await group.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout); } } }