Netty的ByteToMessageDecoder/LengthFieldBasedFrameDecoder

时间:2023-03-08 16:39:01

是个inbound handler,channelRead方法里面,用一个bytebuf(cumulation)来把下一个数据包和当前这一个拼在一起,以免同一个请求被拆包。然后callDecode,里面调用decode这个方法

decode是被子类重写的方法,像rocketMq的NettyDecoder其实主要的逻辑还是在它继承的LengthFieldBasedFrameDecoder中,而LengthFieldBasedFrameDecoder又继承了ByteToMessageDecoder。

所以LengthFieldBasedFrameDecoder就是一种解决粘包的方案:在报文头中用固定长度字段表示当前报文长度。

super(FRAME_MAX_LENGTH, 0, 4, 0, 4);

/**
* Creates a new instance.
*
* @param maxFrameLength-----------最大帧长,Integer.parseInt(System.getProperty("com.rocketmq.remoting.frameMaxLength", "16777216"));
* the maximum length of the frame. If the length of the frame is
* greater than this value, {@link TooLongFrameException} will be
* thrown.
* @param lengthFieldOffset----------描述当前帧长的第一个字节的起始位置,因为有时候信息并不是直接以帧长开头,有可能前面还有别的信息
* the offset of the length field
* @param lengthFieldLength----------描述当前帧长的字节的个数
* the length of the length field
* @param lengthAdjustment----------比如实际帧长是40,描述帧长的字节是4,如果你的lengthFieldLength的值是44(有的人会把描述的数据本身长度也算进去),那么就得有4的调整,才准确
* the compensation value to add to the value of the length field
* @param initialBytesToStrip----------解析时候需要跳过的字节长,这个是干啥?
* the number of first bytes to strip out from the decoded frame
*/

callDecode调用decode传入三个参数: context, bytebuf, out, 第三个out是一个list,里面放的是解决了拆包粘包问题之后解析出来的完整的一个请求,然后for循环发起channelread,RocktMq server的源码里是封装成一个

command对象,然后发起链式的处理