Netty之ChannelPipeline 和 ChannelHandler

版本为 Netty4.1。

概述

Netty 的 ChannelPipeline 和 ChannelHandler 机制类似于 Servlet 和 Filter 过滤器,这类拦截器实际上是职责链模式的一种变形,主要是为了方便事件的拦截和用户业务逻辑的定制。

Servlet Filter 过滤器提供了一种面向对象的模块化机制,用来将公共人物封装到可插入的组件中。这些组件通过 Web 部署配置文件(web.xml)进行声明,无须改动代码即可添加和删除过滤器。可以对应于程序 Servlet 提供的核心功能进行补充,而不破坏原有的功能。

Netty 的 Channel 过滤器实现原理与 Servlet Filter 机制一致,它将 Channel 的数据管道抽象为 ChannelPipeline,消息在 ChannelPipeline 中流动和传递。ChannelPipeline 持有 I/O 事件拦截器 ChannelHandler 的链表,由 ChannelHandler 来对 I/O 事件进行具体的拦截和处理,可以方便地通过新增和删除 ChannelHandler 来实现不同业务逻辑的定制,能够实现对修改封闭和对扩展到支持。

ChannelPipeline

官网API文档:ChannelPipeline

ChannelPipeline介绍

每一个Channel都拥有自己的ChannelPipeline,它是ChannelHandler的容器,负责ChannelHandler的管理、事件拦截、消息调度。

ChannelPipeline工作原理

ChannelPipeline实际上就是Channel的数据管道,消息从中通过,依次通过每个ChannelHandler并执行相应的处理。
我们通过对ChannelPipeline所持有的ChannelHandler链表进行简单的增删的操作就可以实现不同业务逻辑定制。

下图是Netty API 中ChannelPipeline对事件流的拦截和处理流程的示意图:

                                                 I/O Request
                                            via Channel or
                                        ChannelHandlerContext
                                                      |
  +---------------------------------------------------+---------------+
  |                           ChannelPipeline         |               |
  |                                                  \|/              |
  |    +---------------------+            +-----------+----------+    |
  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  |               |                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  .               |
  |               .                                   .               |
  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
  |        [ method call]                       [method call]         |
  |               .                                   .               |
  |               .                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  |               |                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  +---------------+-----------------------------------+---------------+
                  |                                  \|/
  +---------------+-----------------------------------+---------------+
  |               |                                   |               |
  |       [ Socket.read() ]                    [ Socket.write() ]     |
  |                                                                   |
  |  Netty Internal I/O Threads (Transport Implementation)            |
  +-------------------------------------------------------------------+

事件处理流程
Netty 中的事件分为 inbound 事件和 outbound 事件。inbound 事件通常由 I/O 线程触发,比如:
1. 注册事件 fireChannelRegistered。
2. 连接建立事件 fireChannelActive。
3. 读事件和读完成事件 fireChannelRead、fireChannelReadComplete。
4. 异常通知事件 fireExceptionCaught。
5. 用户自定义事件 fireUserEventTriggered。
6. Channel 可写状态变化事件 fireChannelWritabilityChanged。
7. 连接关闭事件 fireChannelInactive。

outbound 事件通常是由用户主动出发的 I/O 事件,比如:
1. 端口绑定 bind。
2. 连接服务端 connect。
3. 写事件 write。
4. 刷新时间 flush。
5. 读事件 read。
6. 主动断开连接 disconnect。
7. 关闭 channel 事件 close。


ChannelHandler

官网API文档:ChannelHandler
ChannelHandler 类似于 Servlet 的 Filter 过滤器,负责对 I/O 事件进行拦截和处理,可以选择性地处理,也可以透传和终止事件的传递。基于 ChannelHandler 接口,用户可以方便地进行业务逻辑定制,比如打印日志,统一封装异常信息等。

ChannelHandler、ChannelInboundHandler 和 ChannelOutboundHandler 接口中,提供了许多方法。在实际使用中,用户往往只需要其中的一两个。为了方便用户使用,有几个抽象类(ChannelHandlerAdapter、ChannelInboundHandlerAdapter、ChannelOutboundHandlerAdapter)提供了一些默认实现,如此用户只需要实现自己关心的方法便可。

ChannelHandler的执行顺序

值得注意的一点是,ChannelHandler的执行顺序与向ChannelPipeline添加时的顺序有关。因此,在进行类似编解码这样前后依赖的操作时,对ChannelHandler添加的顺序要格外注意。

ChannelHandlerAdapter

ChannelHandlerAdapter 抽象类,提供了 ChannelHandler 接口方法的默认实现,以及根据注解判断该类是否可共享的 isSharable 方法。

ChannelInboundHandlerAdapter、ChannelOutboundHandlerAdapter 分别提供了 ChannelInboundHandler 和 ChannelOutboundHandler 的默认实现。以 ChannelInboundHandlerAdapter 为例,其大多数方法的默认实现都是调用 ChannelHandlerContext 的类似方法,作用为向后传递。

猜你喜欢

转载自blog.csdn.net/Code_shadow/article/details/81810134