INDEX
基本介绍
Netty 通过编码器将消息转换成通信数据进行传输
Netty 通过编码器将接收到的通讯数据转换成消息以使用
编解码器可能在一次 出站、入站中被多次调用,直到出入站数据不再满足编解码条件
-
Decoder
- 继承
ChannelInboundHandlerAdapter
- 需要实现
decode
方法
protected abstract void decode(ChannelHandlerContext ctx, I msg, List<Object> out) throws Exception;
- 如
MessageToMessageDecoder
、ByteToMessageDecoder
、ReplayingDecoder<Void>
- 继承
-
Encoder
- 继承
ChannelOutboundHandlerAdapter
- 需要实现
encode
方法
protected abstract void encode(ChannelHandlerContext ctx, I msg, List<Object> out) throws Exception;
- 如
MessageToMessageEncoder
、MessageToByteEncoder
- 继承
-
编解码方法
encode
、decode
在ChannelHandler
的读写方法中被调用
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
CodecOutputList out = null;
try {
if (acceptOutboundMessage(msg)) {
out = CodecOutputList.newInstance();
@SuppressWarnings("unchecked")
I cast = (I) msg;
try {
encode(ctx, cast, out);
} finally {
ReferenceCountUtil.release(cast);
}
// 略
} else {
ctx.write(msg, promise);
}
} catch (EncoderException e) {
throw e;
} catch (Throwable t) {
throw new EncoderException(t);
} finally {
// 略
}
}
常见编解码器
ReplayingDecoder<S>
<S>
表示用户状态管理类型,Void
时表示不需要状态管理- 不需要调用
readableBytes()
方法 - 缺点
- 不能支持所有
ByteBuf
操作,如果使用了不支持的方法,会抛出UnsupportedOperationException
- 部分情况下效率较低,如网络缓慢且消息格式复杂时(消息会拆碎成多个片段)
- 不能支持所有
LineBasedFrameDecoder
- 基于行尾控制符
\r
或\r\n
作为分隔符解析数据
DelimiterBasedFrameDecoder
- 基于自定义特殊字符作为分隔符解析数据
HttpObjectDecoder
- Http 数据解码器
LengthFieldBasedFrameDecoder
- 通过指定长度标识整个数据包,可以自动处理黏包、半包消息