• io.netty.channel.ChannelPipeline 这个Java类中, 有这样的注释

三.Netty中的基本概念 - 图1

1.事件

  • 上文中我们了解到Netty是一个事件驱动的网络模型

三.Netty中的基本概念 - 图2

  • 所以在Netty编程中, 一切皆事件, 我们解决问题的最小单元就是事件
  • Netty把很多操作, 都切分开来抽象成了一堆事件
  • 先暂时不要细究事件是个啥, 你先把它当做成一个在handler之间流转的Java对象, 后面我们再详细讨论

    2.pipeline

    现在你知道了Netty里面把万物都抽象成了事件, 好了, 我们现在需要了解一下事件是怎么流动的
    三.Netty中的基本概念 - 图3

  • 这里Netty设计了一个pipeline的概念 (实际上是一种责任链的设计模式)

    2.1 出站与入站

  • pipeline有两条平行线, 这两条线就是事件流转的路线

  • 入站线路: 一条起点是socket, 接收网络数据之后, 数据包会变换成各种事件, 顺着入站线路流转
  • 出站线路: 另一条的终点是socket, 我们的程序可以把事件丢入出站线路

    2.2 ChannelHandler

  • ChannelHandler在pipeline上处理各种事件的对象

  • 而这些handler又分为
  • 专门处理入站事件的 ChannelInboundHandler
  • 专门处理出站事件的 ChannelOutboundHandler

    2.2.1 ChannelInboundHandler

  • io.netty.channel.ChannelInboundHandler

下面三个方法比较重要

  1. public interface ChannelInboundHandler extends ChannelHandler {
  2. /**
  3. * 建立TCP连接的时候会被调用
  4. */
  5. void channelActive(ChannelHandlerContext ctx) throws Exception;
  6. /**
  7. * 当读取到新的数据的时候会被调用
  8. * 这里需要解决半包粘包问题
  9. */
  10. void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception;
  11. /**
  12. * 当前读操作读取的最后一条消息被channelRead使用
  13. * 然后会调用此方法
  14. */
  15. void channelReadComplete(ChannelHandlerContext ctx) throws Exception;
  16. }

2.2.2 ChannelOutboundHandler

  • io.netty.channel.ChannelOutboundHandler

    1. public interface ChannelOutboundHandler extends ChannelHandler {
    2. /**
    3. * ChannelHandlerContext
    4. * ctx.writeAndFlush(msg);
    5. * ctx.write(msg);
    6. */
    7. void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception;
    8. /**
    9. * ChannelHandlerContext
    10. * ctx.writeAndFlush(msg);
    11. * ctx.flush(msg);
    12. */
    13. void flush(ChannelHandlerContext ctx) throws Exception;
    14. }

    2.2.3 ChannelDuplexHandler

  • 结合了InboundHandler和OutboundHandler的handler

    1. public class ChannelDuplexHandler extends ChannelInboundHandlerAdapter
    2. implements ChannelOutboundHandler {
    3. }

    2.2.3 ChannelHandlerContext

    好了有pipeline, 有handler, 那么如何控制handler流转呢?
    一个handler处理完之后, 是该继续入站, 还是出站呢?

  • io.netty.channel.ChannelHandlerContext

这个接口是操作事件在pipeline中流转的方向

  • ctx.fireChannelRead() : 可以将事件对象以入站的方向,向后流转, 转给其他ChannelInboundHandler处理
  • ctx.write(): 可以将事件传送到出站方向的下一个handler的write()方法中
  • ctx.writeAndFlush() : 可以将事件传送到出站方向的下一个handler的write()方法中, 再调用flush()
  • ctx.channel().write() : 将事件送到整个pipeline的尾部, 再出站, handler逐个处理

三.Netty中的基本概念 - 图4