Netty解码器也是非常重要的一个模块, 服务端接收到客户端发送过来的消息, 准确说是字节数组, Netty底层已经将它们读取成ByteBuf了, 但是这些ByteBuf是没有任何含义的, 就像一些'散兵游勇', 我们现在要把它们解码成我们认识的业务类.
下面的代码是摘取自RocketMQ源码
this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupSelector)
.channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.SO_KEEPALIVE, false)
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSndBufSize())
.childOption(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketRcvBufSize())
.localAddress(new InetSocketAddress(this.nettyServerConfig.getListenPort()))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline()
.addLast(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, handshakeHandler)
.addLast(defaultEventExecutorGroup,
encoder,
new NettyDecoder(),
new IdleStateHandler(0, 0, nettyServerConfig.getServerChannelMaxIdleTimeSeconds()),
connectionManageHandler,
serverHandler
);
}
});
大家可以看到一个NettyDecoder类, 它就是一个解码器.
解码器一般分为两类, 一类是消息帧解码器, 一类是业务解码器. 消息帧解码器就是将那些'散兵游勇'解码成符合事先约定好的消息格式, 也就是解决消息粘包的问题; 经过消息帧解码器, 解码成具有含义的消息帧, 再通过业务解码器将消息帧解码成我们认识的业务类.
Netty提供了4个主要的消息帧解码器 :
FixedLengthFrameDecoder 基于固定长度解码器
LineBasedFrameDecoder 基于换行符解码器
DelimiterBasedFrameDecoder 基于分隔符解码器
LengthFieldBasedFrameDecoder 基于长度解码器
RocketMQ中的解码器NettyDecoder也是继承了LengthFieldBasedFrameDecoder解码器. 再接下来的文章中我们会详细说明这些解码器如何实现解码.