一、简介

ChannelPipeline和ChannelHandler也是netty中重要的组件,并且它们的关系是较为亲密的,所以在这里一起介绍

二、ChannelPipeline

每一个新创建的Channel都会绑定一个流水线ChannelPipelineChannelPipeline是一个由多个ChannelHandler(实际上是ChannelHandlerContext,不过它只是在ChannelHandler里面再包了一层而已)组成的一个双向链表,ChannelPipeline与Channel、ChannelHandler的关系如下:

如上图,ChannelHandler可分为两大类,入站处理器ChannelInboundHandler以及出站处理器ChannelOutboundHandler,前面会再具体介绍

ChannelPipeline的工作流程,如下:

  1. ChannelPipeline流传事件时,判断下一个ChannelHandler的类型是否与事件运行方向相匹配
  2. 如下面例子,如果是入站事件,那么事件会先流经入站处理器2,再流经入站处理器4,会跳过出站处理器
  3. 反之,如果是出站事件,会先流经出站处理器3,再流经出站处理器1

ChannelPipeline的入站操作,告诉ChannelInboundHandler在ChannelPipeline中产生的事件,如下

fireChannelRegistered调用下一个ChannelInboundHandler的channelRegistered办法
fireChannelUnregistered调用下一个ChannelInboundHandler的fireChannelUnregistered办法
fireChannelActive调用下一个ChannelInboundHandler的fireChannelActive办法
fireChannelInactive调用下一个ChannelInboundHandler的fireChannelInactive办法
fireExceptionCaught调用下一个ChannelInboundHandler的fireExceptionCaught办法
fireUserEventTriggered调用下一个ChannelInboundHandler的fireUserEventTriggered办法
fireChannelRead调用下一个ChannelInboundHandler的fireChannelRead办法
fireChannelReadComplete调用下一个ChannelInboundHandler的fireChannelReadComplete办法
fireChannelWritabilityChanged调用下一个ChannelInboundHandler的fireChannelWritabilityChanged办法

ChannelPipeline的出站操作,如下

bind将Channel绑定到一个本地地址,将调用下一个ChannelOutboundHandler的bind办法
connect将Channel连贯到一个近程地址,将调用下一个ChannelOutboundHandler的connect办法
disconnect将Channel断开连接,将调用下一个ChannelOutboundHandler的disconnect办法
close将Channel敞开,将调用下一个ChannelOutboundHandler的close办法
deregister将Channel从EventLoop中登记,将调用下一个ChannelOutboundHandler的deregister办法
flush冲刷Channel里的缓存数据,将调用下一个ChannelOutboundHandler的flush办法
write将音讯写入Channel,将调用下一个ChannelOutboundHandler的write办法
writeAndFlush这是个write()和flush()办法的联合
read申请从Channel中读取更多数据,将调用下一个ChannelOutboundHandler的read办法

三、ChannelHandler

下面曾经介绍ChannelHandler有两个重要的子接口,别离是ChannelInboundHandler 和 ChannelOutboundHandler

  1. ChannelInboundHandler:解决入站数据以及各种状态变动
  2. ChannelOutboundHandler:解决出站数据并且容许拦挡所有操作

ChannelInboundHandler的生命周期办法将会在数据被接管时或者与其对应的Channel状态产生扭转时被调用,如下

channelRegistered当Channel曾经注册到对应的EventLoop时被调用
channelUnregistered当Channel从它的EventLoop登记时被调用
channelActive当Channel处于活动状态时被调用
channelInactive当Channel来到活动状态时被调用
channelReadComplete当Channel的一个读操作实现时被调用
channelRead当Channel读取数据时被调用
channelWritabilityChanged当Channel的可写状态产生扭转时被调用
userEventTriggered当ChannelInboundHandler.fireUserEventTriggered()办法被调用时调用

ChannelOutboundHanlder解决出站操作和数据,办法如下

bind当申请将Channel绑定到本地地址时被调用
connect当申请将Channel连贯到近程节点时被调用
disconnect当申请将Channel从近程节点断开时被调用
close当申请敞开Channel时被调用
deregister当申请将Channel从它的EventLoop登记时被调用
read当申请从Channel读取更多的数据时被调用
flush当申请通过Channel将入队数据冲刷到近程节点时被调用
write当申请通过Channel将数据写到近程节点时被调用

四、总结

每个Channel都绑定了一个ChannelPipeline,而ChannelPipeline又是由一系列的ChannelHandler连贯而成的。当一个入站事件进入时,该事件会从头到尾流经ChannelPipeline的入站处理器ChannelInboundHandler,而当一个出站事件触发时,该事件会从尾到头流经ChannelPipeline的出站处理器ChannelOutboundHandler。