一、简介
ChannelPipeline 和 ChannelHandler 也是 netty 中重要的组件,并且它们的关系是较为亲密的,所以在这里一起介绍
二、ChannelPipeline
每一个 新创建的 Channel
都会绑定一个 流水线 ChannelPipeline
,ChannelPipeline 是一个由多个 ChannelHandler(实际上是 ChannelHandlerContext,不过它只是在 ChannelHandler 里面再包了一层而已)组成的一个双向链表
,ChannelPipeline 与 Channel、ChannelHandler 的关系如下:
如上图,ChannelHandler 可分为两大类,入站处理器 ChannelInboundHandler 以及出站处理器 ChannelOutboundHandler
,前面会再具体介绍
ChannelPipeline 的工作流程,如下:
- ChannelPipeline 流传事件时,判断下一个 ChannelHandler 的类型是否与事件运行方向相匹配
- 如下面例子,如果是
入站事件,那么事件会先流经入站处理器 2,再流经入站处理器 4,会跳过出站处理器
。 - 反之,如果是
出站事件,会先流经出站处理器 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
- ChannelInboundHandler:
解决入站数据以及各种状态变动
- 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。