Netty 的 ChannelPipeline 我们可以简单的理解为一个 Channel 数据管道,消息在 ChannelPipeline 中流动和传递。ChannelPipeline 持有 I/O 事件的连接器 ChannelHandler 的链表。它是 ChannelHandler 的容器,负责 ChannelHandler 的管理和事件拦截与调度。在Channel创建的时候,会同时创建ChannelPipeline。
ChannelHandler 像一个拦截器,它在 ChannelPipeline 中,比如有一串数据,在 ChannelPipeline 流通,那么 ChannelHandler 就会对这部分数据进行一一拦截处理,如果符合自己的处理规则,就对数据进行处理,如果不符合就让数据流通。ChannelHandler 有系统自带的 handler 用户也可以自定义 Handler 来实现自定义逻辑。
ChannelPipeline 的处理流程如下图:
从图中我们可以看到有种类型的事件,一个是 inbound 事件,另外一个就是 outbound 事件。inbound 事件通常由 I/O 线程触发,例如 TCP 链路建立事件,链路关闭事件,读事件,异常通知事件等等。outbound 事件通常是由用户主动发起的网络 I/O 操作,例如用户发起的连接操作、绑定操作、消息发送等操作。
上图的事件处理流程大概:
当发送某个 I/O 事件的时候,例如链路建立,链路关闭,读取操作完成等,都会产生一个事件,事件在 pipeline 中得到传播和处理,它是事件处理总入口。由于网络 I/O 相关的事件有限,所以 Netty 对这些事件进行了统一的抽象。pipeline 里面以 fireXXX 命名的方法都是从 I/O 线程流向用户业务 Handler 的 inbound 事件。
由用户线程或者代码发起 I/O 操作被称为 outbound 事件,事实上 inbound 和 outbound 是 netty 自身根据事件在 pipeline 中的流向抽象出来的术语。
Netty 中有自带的 ChannelHandler 实现,用户也可以按照自己的诉求,自定义 Handler。因为 ChannelHandler 是一个接口,所以任何实现该接口的都需要实现里面所有的方法,因此就有了 ChannelHandlerAdapter 类。用户可以只实现自己感兴趣的事件。Netty 框架提供了 ChannelInboundHandlerAdapter、ChannelOutboundHandlerAdapter 和 ChannelDuplexHandler 三种适配类。我们在使用的时候,只需要实现我们关注的方法就可以了。
每个 ChannelHandler 通过 add 方法加入到 ChannelPipeline 中去的时候,会创建一个对应的 ChannelHandlerContext,并且绑定,ChannelPipeline 实际维护的是 ChannelHandlerContext 的关系。在 DefaultChannelPipeline 源码中可以看到会保存第一个 ChannelHandlerContext 以及最后一个 ChannelHandlerContext 的引用。
ChannelPipeline 是 ChannelHandler 的管理容器,负责 ChannelHandler 的查询、添加、替换和删除。每个 Channel 都会有一个 ChannelPipeline , 它里面会管理 ChannelHandler ,用来处理 inbound 和 outbound 相关事件。inbound 和 outbound 是自身根据事件在 pipeline 中的流向来定义的,用户线程写入的数据叫 outbound,从底层读取数据就是 inbound。