using DotNetty.Buffers; using DotNetty.Transport.Channels; using Microsoft.Extensions.Logging; using NearCardAttendance.Service.TcpServer.Protocol; using System; using System.Text; namespace NearCardAttendance.Service.TcpServer.Handler { public class ProtocolHandler : SimpleChannelInboundHandler { private IByteBuffer? buffer; private readonly ILogger _logger; public ProtocolHandler(ILogger logger) { _logger = logger; } public override async void ChannelActive(IChannelHandlerContext context) { // Handle channel active event } public override void ChannelInactive(IChannelHandlerContext context) { ReleaseBuffer(); base.ChannelInactive(context); } protected override void ChannelRead0(IChannelHandlerContext context, IByteBuffer message) { try { string content = message.ToString(Encoding.ASCII); _logger.LogInformation($"{nameof(ProtocolHandler)} -- {nameof(ChannelRead0)} -- 最开始接受内容:{content}"); ProcessMessage(context, content); } catch (Exception ex) { ReleaseBuffer(); _logger.LogInformation($"{nameof(ProtocolHandler)} --- {nameof(ChannelRead0)} 处理出错\n{ex.Message}\n{ex.StackTrace}"); } } private void ProcessMessage(IChannelHandlerContext context, string content) { buffer ??= Unpooled.Buffer(); byte[] bytes = Encoding.ASCII.GetBytes(content); buffer.WriteBytes(Unpooled.WrappedBuffer(bytes)); if (int.TryParse(buffer.ToString(Encoding.ASCII).Substring(0, 4), out int messageLength)) { Console.WriteLine(buffer.ToString(Encoding.ASCII)); if (buffer.ToString(Encoding.ASCII).Length == messageLength) { //var parser = buffer.ToString(Encoding.ASCII); ProtocolParser parser = new(buffer.ToString(Encoding.ASCII)); context.FireChannelRead(parser); //Console.WriteLine($"发送正常:{parser}"); //ProtocolWrapper wrapper = new ProtocolWrapper("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss")); //Console.WriteLine(wrapper.GenerateProtocolString()); //Console.WriteLine($"length:{parser.MessageLength},func_no:{parser.FuncNo},seq_no:{parser.SeqNo},data:{parser.Data}"); ReleaseBuffer(); } else if (buffer.ToString(Encoding.ASCII).Length > messageLength) { string inputString = buffer.ToString(Encoding.ASCII); var nextMessageLength = messageLength; var startIndex = 0; var messagesStringLength = 0; List messages = new List(); while (startIndex < inputString.Length) { try { string message = inputString.Substring(startIndex, nextMessageLength); messages.Add(message); startIndex += nextMessageLength; if (startIndex + 4 <= inputString.Length) { if (!int.TryParse(inputString.Substring(startIndex, 4), out nextMessageLength)) { break; } } else { break; } } catch (Exception) { break; } } foreach (var message in messages) { ProtocolParser parser = new(message); context.FireChannelRead(parser); messagesStringLength += message.Length; // Console.WriteLine(message); } // 过长且不完整 if (inputString.Length > messageLength) { var overLongbuffer = Unpooled.Buffer(); overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(inputString.Substring(messageLength, inputString.Length- messageLength)))); ReleaseBuffer(); buffer = overLongbuffer; } // 数据完整 if (inputString.Length ==messageLength) { ReleaseBuffer(); } //Console.WriteLine($"{stringLength},{inputString.Length}"); // var parser = buffer.ToString(Encoding.ASCII).Substring(0, messageLength); //ProtocolParser parser = new(buffer.ToString(Encoding.ASCII).Substring(0, messageLength)); //context.FireChannelRead(parser); ////ReleaseBuffer(); //var overLongbuffer = Unpooled.Buffer(); //Console.WriteLine($"过长消息:{buffer.ToString(Encoding.ASCII).Substring(messageLength)}"); //overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(buffer.ToString(Encoding.ASCII).Substring(messageLength)))); //ReleaseBuffer(); //buffer = overLongbuffer; //Console.WriteLine($"剩余消息{buffer.ToString(Encoding.ASCII)}"); } } } private void ProcessMessage2(IChannelHandlerContext context, string content) { buffer ??= Unpooled.Buffer(); byte[] bytes = Encoding.ASCII.GetBytes(content); buffer.WriteBytes(Unpooled.WrappedBuffer(bytes)); if (int.TryParse(buffer.ToString(Encoding.ASCII).Substring(0, 4), out int messageLength)) { Console.WriteLine(buffer.ToString(Encoding.ASCII)); if (buffer.ToString(Encoding.ASCII).Length == messageLength) { //var parser = buffer.ToString(Encoding.ASCII); ProtocolParser parser = new(buffer.ToString(Encoding.ASCII)); context.FireChannelRead(parser); Console.WriteLine($"发送正常:{parser}"); //ProtocolWrapper wrapper = new ProtocolWrapper("82", parser.SeqNo, DateTime.Now.ToString("yyyyMMddHHmmss")); //Console.WriteLine(wrapper.GenerateProtocolString()); Console.WriteLine($"length:{parser.MessageLength},func_no:{parser.FuncNo},seq_no:{parser.SeqNo},data:{ parser.Data}"); ReleaseBuffer(); } else if (buffer.ToString(Encoding.ASCII).Length > messageLength) { // var parser = buffer.ToString(Encoding.ASCII).Substring(0, messageLength); ProtocolParser parser = new(buffer.ToString(Encoding.ASCII).Substring(0, messageLength)); context.FireChannelRead(parser); //ReleaseBuffer(); var overLongbuffer = Unpooled.Buffer(); Console.WriteLine($"过长消息:{buffer.ToString(Encoding.ASCII).Substring(messageLength)}"); overLongbuffer.WriteBytes(Unpooled.WrappedBuffer(Encoding.ASCII.GetBytes(buffer.ToString(Encoding.ASCII).Substring(messageLength)))); ReleaseBuffer(); buffer = overLongbuffer; Console.WriteLine($"剩余消息{buffer.ToString(Encoding.ASCII)}"); } } } private void ReleaseBuffer() { buffer?.Release(); buffer = null; } } }