Netty 源码分析 08 编码Codec 01

Netty 源码分析 08 编码Codec 01

Netty 源码分析 08 编码Codec 01

Netty 源码分析 08 编码Codec 01

Netty 源码分析 08 编码Codec 01

Netty 源码分析 08 编码Codec 01

4. Cumulator

Cumulator ,是 ByteToMessageDecoder 的内部接口。中文翻译为“累加器”,用于将读取到的数据进行累加到一起,然后再尝试解码,从而实现拆包

也是因为 Cumulator 的累加,所以能将不完整的包累加到一起,从而完整。当然,累加的过程,没准又进入了一个不完整的包。所以,这是一个不断累加,不断解码拆包的过程。

  • 对于 Cumulator#cumulate(ByteBufAllocator alloc, ByteBuf cumulation, ByteBuf in) 方法,将原有 cumulation 累加上新的 in ,返回“新”的 ByteBuf 对象。
  • 如果 in 过大,超过 cumulation 的空间上限,使用 alloc 进行扩容后再累加。

4.1 MERGE_CUMULATOR

MERGE_CUMULATOR 思路是,不断使用老的 ByteBuf 累积。如果空间不够,扩容出新的 ByteBuf ,再继续进行累积。

4.2 COMPOSITE_CUMULATOR

COMPOSITE_CUMULATOR 思路是,使用 CompositeByteBuf ,组合新输入的 ByteBuf 对象,从而避免内存拷贝。

Netty 源码分析 08 编码Codec 01

默认情况下,ByteToMessageDecoder 使用 MERGE_CUMULATOR 作为累加器。

5. ByteToMessageDecoder

io.netty.handler.codec.ByteToMessageDecoder ,继承 ChannelInboundHandlerAdapter 类,抽象基类,负责将 Byte 解码成 Message 

5.2 channelRead

#channelRead(ChannelHandlerContext ctx, Object msg) 方法,读取到新的数据,进行解码

5.3 callDecode

#callDecode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) 方法,执行解码。而解码的结果,会添加到 out 数组中

5.3.1 decodeRemovalReentryProtection

#decodeRemovalReentryProtection(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) 方法,执行解码。如果 Handler 准备移除,在解码完成后,进行移除

5.4 channelReadComplete

#channelReadComplete(ChannelHandlerContext ctx) 方法

5.5 channelInactive

#channelInactive(ChannelHandlerContext ctx) 方法,通道处于未**( Inactive ),解码完剩余的消息,并释放相关资源

调用 #channelInputClosed(ChannelHandlerContext ctx, boolean callChannelInactive) 方法,执行 Channel 读取关闭的逻辑

5.6 userEventTriggered

#userEventTriggered(ChannelHandlerContext ctx, Object evt) 方法,处理 ChannelInputShutdownEvent 事件,即 Channel 关闭读取

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Codec 之 ByteToMessageDecoder(二)FrameDecoder

1. 概述

在 《精尽 Netty 源码解析 —— Codec 之 ByteToMessageDecoder(一)》 中,我们看到 ByteToMessageDecoder 有四个 FrameDecoder 实现类:

  • ① FixedLengthFrameDecoder ,基于固定长度消息进行粘包拆包处理的。
  • ② LengthFieldBasedFrameDecoder ,基于消息头指定消息长度进行粘包拆包处理的。
  • ③ LineBasedFrameDecoder ,基于换行来进行消息粘包拆包处理的。
  • ④ DelimiterBasedFrameDecoder ,基于指定消息边界方式进行粘包拆包处理的。

Netty 源码分析 08 编码Codec 01

Netty 源码分析 08 编码Codec 01

3. LineBasedFrameDecoder

io.netty.handler.codec.LineBasedFrameDecoder ,继承 ByteToMessageDecoder 抽象类,基于换行来进行消息粘包拆包处理的。

它会处理 "\n" 和 "\r\n" 两种换行符。

3.3 findEndOfLine

#findEndOfLine(final ByteBuf buffer) 方法,获得换行符的位置。代码如下

4. LengthFieldBasedFrameDecoder

io.netty.handler.codec.LengthFieldBasedFrameDecoder ,继承 ByteToMessageDecoder 抽象类,基于消息头指定消息长度进行粘包拆包处理的。

5. DelimiterBasedFrameDecoder

io.netty.handler.codec.DelimiterBasedFrameDecoder ,继承 ByteToMessageDecoder 抽象类,基于指定消息边界方式进行粘包拆包处理的。