上一篇【第80篇】Netty学习路线图与总结——从入门到精通的完整路径
下一篇【第82篇】ChannelOutboundBuffer源码深度解析——Netty写缓冲区的秘密
一、Codec继承体系
ByteToMessageDecoder(字节→消息) ├── FixedLengthFrameDecoder ├── LengthFieldBasedFrameDecoder ├── LineBasedFrameDecoder └── DelimiterBasedFrameDecoder MessageToMessageDecoder(消息→消息) └── StringDecoder, ObjectDecoder... MessageToByteEncoder(消息→字节) └── LengthFieldPrepender, StringEncoder... ByteToMessageCodec(组合:byte↔msg)二、ByteToMessageDecoder核心
publicabstractclassByteToMessageDecoderextendsChannelInboundHandlerAdapter{ByteBufcumulation;// 累积缓冲区// 收到新数据publicvoidchannelRead(ChannelHandlerContextctx,Objectmsg){ByteBufdata=(ByteBuf)msg;cumulation=cumulator.cumulate(ctx.alloc(),cumulation,data);callDecode(ctx,cumulation,out);}// 用户实现:解码数据protectedabstractvoiddecode(ChannelHandlerContextctx,ByteBufin,List<Object>out);}三、callDecode循环解码
protectedvoidcallDecode(ChannelHandlerContextctx,ByteBufin,List<Object>out){while(in.isReadable()){intoldInputLength=in.readableBytes();decode(ctx,in,out);// 调用用户decode()if(out.isEmpty()){if(oldInputLength==in.readableBytes())break;// 没消费→退出continue;// 消费了但没产出,继续}// 产出消息→触发channelReadfireChannelRead(ctx,out,out.size());out.clear();}}四、cumulation两种模式
// MERGE:复制合并ByteBufbuffer=alloc.buffer(old.readableBytes()+in.readableBytes());buffer.writeBytes(old).writeBytes(in);old.release();in.release();// COMPOSITE:零拷贝组合CompositeByteBufcomposite=alloc.compositeBuffer();composite.addComponents(true,old,in);五、总结
| 机制 | 说明 |
|---|---|
| cumulation | 累积不完整数据 |
| callDecode | 循环解码直到无数据 |
| 安全保护 | 没消费+没产出→防止死循环 |
上一篇【第80篇】Netty学习路线图与总结——从入门到精通的完整路径
下一篇【第82篇】ChannelOutboundBuffer源码深度解析——Netty写缓冲区的秘密