You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
3.0 KiB

  1. using DotNetty.Transport.Bootstrapping;
  2. using DotNetty.Transport.Channels;
  3. using DotNetty.Transport.Channels.Sockets;
  4. using JT808.DotNetty.Core.Codecs;
  5. using JT808.DotNetty.Core.Configurations;
  6. using JT808.DotNetty.Udp.Handlers;
  7. using Microsoft.Extensions.DependencyInjection;
  8. using Microsoft.Extensions.Hosting;
  9. using Microsoft.Extensions.Logging;
  10. using Microsoft.Extensions.Options;
  11. using System;
  12. using System.Net;
  13. using System.Runtime.InteropServices;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. namespace JT808.DotNetty.Udp
  17. {
  18. /// <summary>
  19. /// JT808 Udp网关服务
  20. /// </summary>
  21. internal class JT808UdpServerHost : IHostedService
  22. {
  23. private readonly IServiceProvider serviceProvider;
  24. private readonly JT808Configuration configuration;
  25. private readonly ILogger<JT808UdpServerHost> logger;
  26. private MultithreadEventLoopGroup group;
  27. private IChannel bootstrapChannel;
  28. public JT808UdpServerHost(
  29. IServiceProvider provider,
  30. ILoggerFactory loggerFactory,
  31. IOptions<JT808Configuration> jT808ConfigurationAccessor)
  32. {
  33. serviceProvider = provider;
  34. configuration = jT808ConfigurationAccessor.Value;
  35. logger=loggerFactory.CreateLogger<JT808UdpServerHost>();
  36. }
  37. public Task StartAsync(CancellationToken cancellationToken)
  38. {
  39. group = new MultithreadEventLoopGroup();
  40. Bootstrap bootstrap = new Bootstrap();
  41. bootstrap.Group(group);
  42. bootstrap.Channel<SocketDatagramChannel>();
  43. if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
  44. || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
  45. {
  46. bootstrap
  47. .Option(ChannelOption.SoReuseport, true);
  48. }
  49. bootstrap
  50. .Option(ChannelOption.SoBroadcast, true)
  51. .Handler(new ActionChannelInitializer<IChannel>(channel =>
  52. {
  53. IChannelPipeline pipeline = channel.Pipeline;
  54. using (var scope = serviceProvider.CreateScope())
  55. {
  56. pipeline.AddLast("jt808UdpDecoder", scope.ServiceProvider.GetRequiredService<JT808UdpDecoder>());
  57. pipeline.AddLast("jt808UdpService", scope.ServiceProvider.GetRequiredService<JT808UdpServerHandler>());
  58. }
  59. }));
  60. logger.LogInformation($"JT808 Udp Server start at {IPAddress.Any}:{configuration.UdpPort}.");
  61. return bootstrap.BindAsync(configuration.UdpPort)
  62. .ContinueWith(i => bootstrapChannel = i.Result);
  63. }
  64. public async Task StopAsync(CancellationToken cancellationToken)
  65. {
  66. await bootstrapChannel.CloseAsync();
  67. var quietPeriod = configuration.QuietPeriodTimeSpan;
  68. var shutdownTimeout = configuration.ShutdownTimeoutTimeSpan;
  69. await group.ShutdownGracefullyAsync(quietPeriod, shutdownTimeout);
  70. }
  71. }
  72. }