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.

187 lines
8.1KB

  1. using DotNetty.Buffers;
  2. using DotNetty.Transport.Channels;
  3. using Microsoft.Extensions.Logging;
  4. using NearCardAttendance.Service.TcpServer.Protocol;
  5. using System;
  6. using System.Text;
  7. namespace NearCardAttendance.Service.TcpServer.Handler
  8. {
  9. public class ProtocolHandler : SimpleChannelInboundHandler<IByteBuffer>
  10. {
  11. private IByteBuffer? buffer;
  12. private readonly ILogger<ProtocolHandler> _logger;
  13. public ProtocolHandler(ILogger<ProtocolHandler> logger)
  14. {
  15. _logger = logger;
  16. }
  17. public override async void ChannelActive(IChannelHandlerContext context)
  18. {
  19. // Handle channel active event
  20. }
  21. public override void ChannelInactive(IChannelHandlerContext context)
  22. {
  23. ReleaseBuffer();
  24. base.ChannelInactive(context);
  25. }
  26. protected override void ChannelRead0(IChannelHandlerContext context, IByteBuffer message)
  27. {
  28. try
  29. {
  30. string content = message.ToString(Encoding.ASCII);
  31. _logger.LogInformation($"{nameof(ProtocolHandler)} -- {nameof(ChannelRead0)} -- 最开始接受内容:{content}");
  32. ProcessMessage(context, content);
  33. }
  34. catch (Exception ex)
  35. {
  36. ReleaseBuffer();
  37. _logger.LogInformation($"{nameof(ProtocolHandler)} --- {nameof(ChannelRead0)} 处理出错\n{ex.Message}\n{ex.StackTrace}");
  38. }
  39. }
  40. private void ProcessMessage(IChannelHandlerContext context, string content)
  41. {
  42. buffer ??= Unpooled.Buffer();
  43. byte[] bytes = Encoding.ASCII.GetBytes(content);
  44. buffer.WriteBytes(Unpooled.WrappedBuffer(bytes));
  45. if (int.TryParse(buffer.ToString(Encoding.ASCII).Substring(0, 4), out int messageLength))
  46. {
  47. Console.WriteLine(buffer.ToString(Encoding.ASCII));
  48. if (buffer.ToString(Encoding.ASCII).Length == messageLength)
  49. {
  50. //var parser = buffer.ToString(Encoding.ASCII);
  51. ProtocolParser parser = new(buffer.ToString(Encoding.ASCII));
  52. context.FireChannelRead(parser);
  53. //Console.WriteLine($"发送正常:{parser}");
  54. //ProtocolWrapper wrapper = new ProtocolWrapper("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss"));
  55. //Console.WriteLine(wrapper.GenerateProtocolString());
  56. //Console.WriteLine($"length:{parser.MessageLength},func_no:{parser.FuncNo},seq_no:{parser.SeqNo},data:{parser.Data}");
  57. ReleaseBuffer();
  58. }
  59. else if (buffer.ToString(Encoding.ASCII).Length > messageLength)
  60. {
  61. string inputString = buffer.ToString(Encoding.ASCII);
  62. var nextMessageLength = messageLength;
  63. var startIndex = 0;
  64. var messagesStringLength = 0;
  65. List<string> messages = new List<string>();
  66. while (startIndex < inputString.Length)
  67. {
  68. try
  69. {
  70. string message = inputString.Substring(startIndex, nextMessageLength);
  71. messages.Add(message);
  72. startIndex += nextMessageLength;
  73. if (startIndex + 4 <= inputString.Length)
  74. {
  75. if (!int.TryParse(inputString.Substring(startIndex, 4), out nextMessageLength))
  76. {
  77. break;
  78. }
  79. }
  80. else
  81. {
  82. break;
  83. }
  84. }
  85. catch (Exception)
  86. {
  87. break;
  88. }
  89. }
  90. foreach (var message in messages)
  91. {
  92. ProtocolParser parser = new(message);
  93. context.FireChannelRead(parser);
  94. messagesStringLength += message.Length;
  95. // Console.WriteLine(message);
  96. }
  97. // 过长且不完整
  98. if (inputString.Length > messageLength)
  99. {
  100. var overLongbuffer = Unpooled.Buffer();
  101. overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(inputString.Substring(messageLength, inputString.Length- messageLength))));
  102. ReleaseBuffer();
  103. buffer = overLongbuffer;
  104. }
  105. // 数据完整
  106. if (inputString.Length ==messageLength)
  107. {
  108. ReleaseBuffer();
  109. }
  110. //Console.WriteLine($"{stringLength},{inputString.Length}");
  111. // var parser = buffer.ToString(Encoding.ASCII).Substring(0, messageLength);
  112. //ProtocolParser parser = new(buffer.ToString(Encoding.ASCII).Substring(0, messageLength));
  113. //context.FireChannelRead(parser);
  114. ////ReleaseBuffer();
  115. //var overLongbuffer = Unpooled.Buffer();
  116. //Console.WriteLine($"过长消息:{buffer.ToString(Encoding.ASCII).Substring(messageLength)}");
  117. //overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(buffer.ToString(Encoding.ASCII).Substring(messageLength))));
  118. //ReleaseBuffer();
  119. //buffer = overLongbuffer;
  120. //Console.WriteLine($"剩余消息{buffer.ToString(Encoding.ASCII)}");
  121. }
  122. }
  123. }
  124. private void ProcessMessage2(IChannelHandlerContext context, string content)
  125. {
  126. buffer ??= Unpooled.Buffer();
  127. byte[] bytes = Encoding.ASCII.GetBytes(content);
  128. buffer.WriteBytes(Unpooled.WrappedBuffer(bytes));
  129. if (int.TryParse(buffer.ToString(Encoding.ASCII).Substring(0, 4), out int messageLength))
  130. {
  131. Console.WriteLine(buffer.ToString(Encoding.ASCII));
  132. if (buffer.ToString(Encoding.ASCII).Length == messageLength)
  133. {
  134. //var parser = buffer.ToString(Encoding.ASCII);
  135. ProtocolParser parser = new(buffer.ToString(Encoding.ASCII));
  136. context.FireChannelRead(parser);
  137. Console.WriteLine($"发送正常:{parser}");
  138. //ProtocolWrapper wrapper = new ProtocolWrapper("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss"));
  139. //Console.WriteLine(wrapper.GenerateProtocolString());
  140. Console.WriteLine($"length:{parser.MessageLength},func_no:{parser.FuncNo},seq_no:{parser.SeqNo},data:{ parser.Data}");
  141. ReleaseBuffer();
  142. }
  143. else if (buffer.ToString(Encoding.ASCII).Length > messageLength)
  144. {
  145. // var parser = buffer.ToString(Encoding.ASCII).Substring(0, messageLength);
  146. ProtocolParser parser = new(buffer.ToString(Encoding.ASCII).Substring(0, messageLength));
  147. context.FireChannelRead(parser);
  148. //ReleaseBuffer();
  149. var overLongbuffer = Unpooled.Buffer();
  150. Console.WriteLine($"过长消息:{buffer.ToString(Encoding.ASCII).Substring(messageLength)}");
  151. overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(buffer.ToString(Encoding.ASCII).Substring(messageLength))));
  152. ReleaseBuffer();
  153. buffer = overLongbuffer;
  154. Console.WriteLine($"剩余消息{buffer.ToString(Encoding.ASCII)}");
  155. }
  156. }
  157. }
  158. private void ReleaseBuffer()
  159. {
  160. buffer?.Release();
  161. buffer = null;
  162. }
  163. }
  164. }