使用SimpleChannelInBoundHandler还是ChannelInBoundHandler

在Echo的案例中,为什么服务端使用的是ChannelInboundHandlerAdapter,而客户端使用的是SimpleChannelInboundHandler。这个问题和两个因素的相互作用有关:业务逻辑如何处理消息以及Netty如何管理资源。

在客户端,当channelRead0方法完成时,你已经有了传入消息,并且已经处理完它了。当该方法返回时,SimpleChannelInboundHandler负责释放指向保存该消息的ByteBuf的内存引用。

在服务端中,你需要将传入的消息回送给发送者(如下代码所示),而write()操作是异步的,知道channelRead()方法返回后可能仍然没有完成。为此,服务端扩展了ChannelInboundHandlerAdapter,其在这个事件点上不会释放消息。

消息在EchoServerHandler的channelReadComplete()方法中,当writeAndFlush()方法被调用时被释放。

1
2
3
4
5
6
7
8

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    ByteBuf in = (ByteBuf) msg;
    System.out.println("Server Received: " + in.toString(StandardCharsets.UTF_8));
    ctx.write(in);
}

对这段讲解不懂的两个点:

  1. SimpleChannelInboundHandler的channelRead0()方法完成之后,释放ByteBuf的操作我并没有看到
  2. 最后为什么说消息在writeAndFlush()方法被调用时被释放,不是很理解ByteBuf被释放的点