Why is ChannelRead not executed?
- Dominant language
- C#
- Stars
- 4.3k
- Forks
- 1k
- PR merge metrics
- No merged PRs in 30d
Description
`using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotNetty.Buffers;
using DotNetty.Codecs;
using DotNetty.Transport.Channels;
namespace MessageServerTest.Netty
{
public class CommunicationDecoder : ByteToMessageDecoder
{
private readonly int _frameFlag = 0x76;
private readonly int _maxFrameLength;
private readonly int _minFrameLength;
private int delimiters = 1;
private IByteBuffer _frameDelimiter;
///
/// 解码
///
/// 数据包 标志
/// 数据包最大长度
/// 数据包最小长度
public CommunicationDecoder(byte frameFlag, int maxFrameLength, int minFrameLength)
{
_frameFlag = frameFlag;
_maxFrameLength = maxFrameLength;
_minFrameLength = minFrameLength;
_frameDelimiter = Unpooled.WrappedBuffer(new[] { frameFlag });
}
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List output)
{
//小于最小帧
if (input.ReadableBytes <= _minFrameLength)
return;
int readLen = -1;
//标记
int originalReadIndex = input.ReaderIndex;
//备份
input.MarkReaderIndex();
//开始标记在第一个位置
if (_frameFlag == input.GetByte(originalReadIndex))
{
input.SetReaderIndex(originalReadIndex + 1);
//结尾标记的位置
readLen = IndexOfEnd(input);
//备份标记
input.ResetReaderIndex();
//未找到结尾标记
if (readLen == -1)
return;
readLen += delimiters;
if (readLen > _maxFrameLength || readLen < _minFrameLength)
{
input.SkipBytes(readLen);
}
else
{
//读取一帧切片数据
IByteBuffer frame = input.ReadSlice(readLen + 1);
//增加引用计数器
frame.Retain();
output.Add(frame);
}
}
else
{
//开始标记的位置
int readIndex = -1;
int seekReaderIndex = input.ReaderIndex + 1;
while (seekReaderIndex < input.WriterIndex)
{
//找到开始标记
if (_frameFlag == input.GetByte(seekReaderIndex))
{
readIndex = seekReaderIndex;
break;
}
seekReaderIndex++;
}
if (readIndex == -1)
return;
//可以读取的 数据长度小于最小帧长度,说明还不够一包数据,等下一次再读取
if (input.ReadableBytes - readIndex < _minFrameLength)
{
input.ResetReaderIndex();//本次跳过 还原ReaderIndex
return;
}
input.SetReaderIndex(readIndex + 1);
readLen = IndexOfEnd(input);
if (readLen == -1)
{
//本次跳过 后面的所有字节
input.SkipBytes(input.ReadableBytes);
}
else if (readLen > _maxFrameLength || readLen < _minFrameLength)//找到帧 但是长度 小于 最小长度 是错误的帧 SkipBytes
{
input.SetReaderIndex(readIndex);
input.SkipBytes(readLen + delimiters);
}
else
{
input.SetReaderIndex(readIndex);
IByteBuffer frame = input.ReadSlice(readLen + delimiters);
frame.Retain();
output.Add(frame);
}
}
}
///
/// 找到结尾标记
///
///
///
private int IndexOfEnd(IByteBuffer haystack)
{
for (int i = haystack.ReaderIndex; i < haystack.WriterIndex; i++)
{
if (haystack.GetByte(i) != 0x55)
{
continue;
}
else
{
if (i == haystack.WriterIndex)
{
return -1;
}
}
return i - haystack.ReaderIndex;
}
return -1;
}
}
}
`
` try
{
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap
.Group(bossGroup, workerGroup)
.Channel()
.Option(ChannelOption.SoBacklog, 8192)
.Option(ChannelOption.TcpNodelay, true)
.ChildHandler(new ActionChannelInitializer(channel =>
{
IChannelPipeline pipeline = channel.Pipeline;
pipeline.AddLast(new IdleStateHandler(120, 0, 0));
pipeline.AddLast(new CommunicationEncoder());
pipeline.AddLast(new CommunicationDecoder(0x76, 2048, 22));
pipeline.AddLast(new MessageServerHandler());
}));
IChannel boundChannel = await bootstrap.BindAsync(9856);
Console.WriteLine("服务端开始监听端口:9856");
_manualResetEvent.Reset();
_manualResetEvent.WaitOne();
await boundChannel.CloseAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
}
finally
{
await Task.WhenAll(
bossGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)),
workerGroup.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1)));
}`
**Client Code:**
` public class MessageClientHandler : ChannelHandlerAdapter
{
public MessageClientHandler()
{
}
public override void ChannelActive(IChannelHandlerContext context) {
var messageBytes = Encoding.UTF8.GetBytes("{\"MessageId\":\"" + Guid.NewGuid().ToString() + "\",\"StatusCode\":200,\"Message\":\"应答成功\"}");
var byteBuffer = Unpooled.Buffer(256);
string serverCode = "86200703079986######";
byteBuffer.WriteByte(0x76);
byteBuffer.WriteShort(4);
byteBuffer.WriteBytes(Encoding.UTF8.GetBytes(serverCode));
byteBuffer.WriteInt(messageBytes.Length);
byteBuffer.WriteBytes(messageBytes);
byteBuffer.WriteByte(0x55);
Console.WriteLine("设备:" + serverCode + ",发送应答报文:" + string.Join(" ", byteBuffer.ToArray()));
context.WriteAsync(byteBuffer);
}
public override void ChannelRead(IChannelHandlerContext context, object message)
{
var byteBuffer = message as IByteBuffer;
if (byteBuffer != null)
{
Console.WriteLine("Received from server: " + byteBuffer.ToString(Encoding.UTF8));
}
context.WriteAsync(message);
}
public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush();
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
Console.WriteLine("Exception: " + exception);
context.CloseAsync();
}
}`
ask for help
Contributor guide
Assessment
This issue has not been assessed yet.