選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

113 行
4.4 KiB

  1. using DotNetty.Buffers;
  2. using DotNetty.Codecs;
  3. using DotNetty.Handlers.Timeout;
  4. using DotNetty.Transport.Bootstrapping;
  5. using DotNetty.Transport.Channels;
  6. using DotNetty.Transport.Channels.Sockets;
  7. using JT808.DotNetty.Client.Handlers;
  8. using Microsoft.Extensions.Logging;
  9. using System;
  10. using System.Runtime.InteropServices;
  11. using Microsoft.Extensions.DependencyInjection;
  12. using System.Net;
  13. using JT808.DotNetty.Client.Metadata;
  14. using JT808.DotNetty.Client.Codecs;
  15. using JT808.DotNetty.Client.Services;
  16. using JT808.Protocol;
  17. using System.Threading.Tasks;
  18. namespace JT808.DotNetty.Client
  19. {
  20. public sealed class JT808TcpClient : IDisposable
  21. {
  22. private MultithreadEventLoopGroup group;
  23. private IChannel clientChannel;
  24. private bool disposed = false;
  25. public JT808DeviceConfig DeviceConfig { get; private set; }
  26. public ILoggerFactory LoggerFactory { get; private set; }
  27. public JT808TcpClient(JT808DeviceConfig deviceConfig, IServiceProvider serviceProvider)
  28. {
  29. DeviceConfig = deviceConfig;
  30. LoggerFactory = serviceProvider.GetRequiredService<ILoggerFactory>();
  31. JT808SendAtomicCounterService jT808SendAtomicCounterService = serviceProvider.GetRequiredService<JT808SendAtomicCounterService>();
  32. JT808ReceiveAtomicCounterService jT808ReceiveAtomicCounterService = serviceProvider.GetRequiredService<JT808ReceiveAtomicCounterService>();
  33. IJT808Config jT808Config = serviceProvider.GetRequiredService<IJT808Config>();
  34. group = new MultithreadEventLoopGroup(1);
  35. Bootstrap bootstrap = new Bootstrap();
  36. bootstrap.Group(group);
  37. bootstrap.Channel<TcpSocketChannel>();
  38. bootstrap
  39. .Option(ChannelOption.Allocator, new UnpooledByteBufferAllocator())
  40. .Handler(new ActionChannelInitializer<IChannel>(channel =>
  41. {
  42. channel.Pipeline.AddLast("jt808TcpBuffer", new DelimiterBasedFrameDecoder(65535,
  43. Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.BeginFlag }),
  44. Unpooled.CopiedBuffer(new byte[] { JT808.Protocol.JT808Package.EndFlag })));
  45. channel.Pipeline.AddLast("systemIdleState", new IdleStateHandler(60, deviceConfig.Heartbeat, 3600));
  46. channel.Pipeline.AddLast("jt808TcpDecode", new JT808ClientTcpDecoder());
  47. channel.Pipeline.AddLast("jt808TcpEncode", new JT808ClientTcpEncoder(jT808Config,jT808SendAtomicCounterService, LoggerFactory));
  48. channel.Pipeline.AddLast("jt808TcpClientConnection", new JT808TcpClientConnectionHandler(this));
  49. channel.Pipeline.AddLast("jt808TcpService", new JT808TcpClientHandler(jT808ReceiveAtomicCounterService,this));
  50. }));
  51. Task.Run(async () =>
  52. {
  53. clientChannel = await bootstrap.ConnectAsync(IPAddress.Parse(DeviceConfig.TcpHost), DeviceConfig.TcpPort);
  54. });
  55. }
  56. public void Send(JT808ClientRequest request)
  57. {
  58. if (disposed) return;
  59. if (clientChannel == null) throw new NullReferenceException("Channel is empty.");
  60. if (request == null) throw new ArgumentNullException("JT808ClientRequest Parameter is empty.");
  61. if (clientChannel.Active && clientChannel.Open)
  62. {
  63. clientChannel.WriteAndFlushAsync(request);
  64. }
  65. }
  66. public bool IsOpen
  67. {
  68. get
  69. {
  70. if (clientChannel == null) return false;
  71. return clientChannel.Active && clientChannel.Open;
  72. }
  73. }
  74. private void Dispose(bool disposing)
  75. {
  76. if (disposed)
  77. {
  78. return;
  79. }
  80. if (disposing)
  81. {
  82. // 清理托管资源
  83. group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
  84. }
  85. disposed = true;
  86. }
  87. ~JT808TcpClient()
  88. {
  89. //必须为false
  90. //这表明,隐式清理时,只要处理非托管资源就可以了。
  91. Dispose(false);
  92. }
  93. public void Dispose()
  94. {
  95. //必须为true
  96. Dispose(true);
  97. //通知垃圾回收机制不再调用终结器(析构器)
  98. GC.SuppressFinalize(this);
  99. }
  100. }
  101. }