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解码器_Netty

Netty提供了4个主要的消息帧解码器 :

FixedLengthFrameDecoder 基于固定长度解码器

LineBasedFrameDecoder 基于换行符解码器

DelimiterBasedFrameDecoder 基于分隔符解码器

LengthFieldBasedFrameDecoder 基于长度解码器

RocketMQ中的解码器NettyDecoder也是继承了LengthFieldBasedFrameDecoder解码器. 再接下来的文章中我们会详细说明这些解码器如何实现解码.

Netty解码器_Netty_02