美文网首页netty
Netty4中Handler的执行顺序以及ctx.close()

Netty4中Handler的执行顺序以及ctx.close()

作者: virtual灬zzZ | 来源:发表于2022-11-02 13:12 被阅读0次

1. ctx.close()会触发当前Handler和当前Handler之前的close事件;

2. channel.close()所有Handler都会触发;

这样的顺序对于write操作和close都是一样道理的。

举例:netty服务端是这个添加顺序

ch.pipeline().addLast(new InboundHandler1());  
ch.pipeline().addLast(new InboundHandler2()); 
ch.pipeline().addLast(new OutboundHandler1());  
ch.pipeline().addLast(new OutboundHandler2()); 

链表中的顺序为head->in1->in2->out1->out2->tail
1、如果在InboundHandler2中执行的是ctx.channel().writeAndFlush,执行顺序是:
InboundHandler1 
InboundHandler2 
OutboundHandler2
OutboundHandler1

结果证明:执行完InboundHandler1、InboundHandler2之后,由于InboundHandler2中执行的是ctx.channel().writeAndFlush,它会直接从tail开始往前找Outbound执行,链表中的顺序为head->in1->in2->out1->out2->tail,所以会执行out2,再执行out1

2、如果在InboundHandler2中执行的是ctx.writeAndFlush,执行顺序是:
InboundHandler1 
InboundHandler2 

结果证明,由于OutboundHandler1与OutboundHandler2的add在InboundHandler2之后,而InboundHandler2中执行的是ctx.writeAndFlush,它会从当前InboundHandler2的位置,往前找Outbound执行,根据链表中的顺序为head->in1->in2->out1->out2->tail,in2之前已经无Outbound,所以不会再有Outbound会执行

上面两个已经能说明问题,为了方便对netty的handler执行不是太熟悉的读者理解,再举个例子:
ch.pipeline().addLast(new OutboundHandler1());  
ch.pipeline().addLast(new OutboundHandler2());  
ch.pipeline().addLast(new InboundHandler1());  
ch.pipeline().addLast(new InboundHandler2()); 
链表中的顺序为head->out1->out2->in1->in2->tail
1、如果在InboundHandler2中执行的是ctx.channel().writeAndFlush,执行顺序是:
InboundHandler1 
InboundHandler2 
OutboundHandler2
OutboundHandler1 

结果证明,执行完InboundHandler2后,由于InboundHandler2中执行的是ctx.channel().writeAndFlush,它会从tail往前找Outbound执行,而链表中的顺序为head->out1->out2->in1->in2->tail,所以会继续执行到out2、out1

2、如果在InboundHandler2中执行的是ctx.writeAndFlush,执行顺序是:
InboundHandler1
InboundHandler2
OutboundHandler2 
OutboundHandler1

结果证明,执行完InboundHandler2后,由于InboundHandler2中执行的是ctx.writeAndFlush,它会从InboundHandler2位置往前找Outbound执行,而链表中的顺序为head->out1->out2->in1->in2->tail,所以会继续执行到out2、out1

核心最容易让人误解的点总结:

1、ctx.writeAndFlush只会从当前的handler位置开始,往前找outbound执行

2、ctx.pipeline().writeAndFlush与ctx.channel().writeAndFlush会从tail的位置开始,往前找outbound执行

相信你看到这里,基本能掌握channelHandlerContext调用与pipeline、channel调用的区别,但我敢肯定你只能记住3~5天就又忘记了;所以我再加一句记忆方法:

每次add一个channelHandler都会创建一个channelHandlerContext与之绑定,channelHandlerContext的作用就是管理它所关联的channelHandler和在同一个pipeline中的其他channelHandler之间的交互,他是什么?他与某个channelHandler绑定,权利有限,只能从当前他所绑定的channelHandler开始搞事情;
而pipeline与channel比较屌,可以指挥从头或者尾开始搞。

注:channelRead以及channelActive等这些都会接着pipeline传递

参考:
一文搞懂Netty中Handler的执行顺序
ctx.close() 和 ctx.channel().close() 到底有何区别?

相关文章

网友评论

    本文标题:Netty4中Handler的执行顺序以及ctx.close()

    本文链接:https://www.haomeiwen.com/subject/nldjtdtx.html