乐趣区

关于java:Netty五ChannelPipeline以及ChannelHandler

一、简介

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。

退出移动版