Netty: handler的执行顺序
作者:互联网
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) |
+-------------------------------------------------------------------+
入站事件由入站处理程序按自下而上的方向进行处理,如图中左侧所示。入站处理程序通常处理图底部的IO线程生成的入站数据。通常通过实际的输入操作(例如{@link SocketChannelread(ByteBuffer)})从远程对等方读取入站数据。如果入站事件超出了顶部入站处理程序的范围,则将其静默丢弃,或者在需要引起注意时将其记录下来。
出站事件由出站处理程序按自上而下的方向进行处理,如图中右侧所示。出站处理程序通常会生成或转换出站流量,例如写请求。如果出站事件超出了底部出站处理程序,则由与Channel关联的IO线程处理。 IO线程通常执行实际的输出操作,例如{@link SocketChannelwrite(ByteBuffer)}。
以上摘自ChannelPipeline.java上的注释
由以上解释可知,把字节读取到ChannelPipeline中,则称为入站,把字节写到ChannelPipeline则成为出站事件,而不是客户端到服务端称为出站,反之为入站这种生硬的解释。
当数据从外界进入本地channel时,这个动作称之为入站,当数据从本地channel发往外界时,这个动作称为出站。如果以客户端主动访问服务端为例,则这个过程分别触发:客户端出站 --> 服务端入站 --> 服务端出站 --> 客户端入站;而如果以服务端主动访问客户端为例,则这个过程分别触发:服务端出站 --> 客户端入站 --> 客户端出站 --> 服务端入站;(这里就是和其他网站解释的不一样的地方,我翻阅了很多人写的文章,都写的是客户端访问服务端,称之为出站,反之为入站!!?,什么鬼,估计是哪抄来的,或者哪死记硬背的得来的)
当发生入站时,Netty框架会顺向遍历Pipeline中的Handler,遇到InBoundHandler或者InOutBoundHandler的子类时,依次触发对象的 channelRead 方法(上一个节点有义务向下一个节点发送Read事件,如果不发,那么中断 channelRead 链);
当发生出站时,Netty框架会逆向遍历Pipeline中的Handler,遇到OutBoundHandler或者InOutBoundHandler的子类时,依次触发对象的 channelActive | write 方法(上一个节点有义务向下一个节点发送Active事件,如果不发,那么中断 channelActive| write 链);
在出站的时候,各个handler是以倒序的方式出去的,如以上图片所示,最后出站的顺序是M M-1 M-2 M-3...
补充:ChannelOutboundHandler 在注册的时候需要放在最后一个ChannelInboundHandler之前,否则将无法传递到ChannelOutboundHandler。
部分内容参考关于Netty Handler入站出站机制详解
标签:Netty,顺序,handler,+-----------+----------+,Handler,入站,出站,服务端,客户端 来源: https://www.cnblogs.com/fanxia/p/14184095.html