Netty4中Handler的執(zhí)行順序以及ctx.close() 與 ctx.channel().close()的區(qū)別

1. ctx.close()會觸發(fā)當(dāng)前Handler和當(dāng)前Handler之前的close事件;

2. channel.close()所有Handler都會觸發(fā);

這樣的順序?qū)τ趙rite操作和close都是一樣道理的。

舉例:netty服務(wù)端是這個添加順序

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中執(zhí)行的是ctx.channel().writeAndFlush,執(zhí)行順序是:
InboundHandler1 
InboundHandler2 
OutboundHandler2
OutboundHandler1

結(jié)果證明:執(zhí)行完InboundHandler1、InboundHandler2之后,由于InboundHandler2中執(zhí)行的是ctx.channel().writeAndFlush,它會直接從tail開始往前找Outbound執(zhí)行,鏈表中的順序為head->in1->in2->out1->out2->tail,所以會執(zhí)行out2,再執(zhí)行out1

2、如果在InboundHandler2中執(zhí)行的是ctx.writeAndFlush,執(zhí)行順序是:
InboundHandler1 
InboundHandler2 

結(jié)果證明,由于OutboundHandler1與OutboundHandler2的add在InboundHandler2之后,而InboundHandler2中執(zhí)行的是ctx.writeAndFlush,它會從當(dāng)前InboundHandler2的位置,往前找Outbound執(zhí)行,根據(jù)鏈表中的順序為head->in1->in2->out1->out2->tail,in2之前已經(jīng)無Outbound,所以不會再有Outbound會執(zhí)行

上面兩個已經(jīng)能說明問題,為了方便對netty的handler執(zhí)行不是太熟悉的讀者理解,再舉個例子:
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中執(zhí)行的是ctx.channel().writeAndFlush,執(zhí)行順序是:
InboundHandler1 
InboundHandler2 
OutboundHandler2
OutboundHandler1 

結(jié)果證明,執(zhí)行完InboundHandler2后,由于InboundHandler2中執(zhí)行的是ctx.channel().writeAndFlush,它會從tail往前找Outbound執(zhí)行,而鏈表中的順序為head->out1->out2->in1->in2->tail,所以會繼續(xù)執(zhí)行到out2、out1

2、如果在InboundHandler2中執(zhí)行的是ctx.writeAndFlush,執(zhí)行順序是:
InboundHandler1
InboundHandler2
OutboundHandler2 
OutboundHandler1

結(jié)果證明,執(zhí)行完InboundHandler2后,由于InboundHandler2中執(zhí)行的是ctx.writeAndFlush,它會從InboundHandler2位置往前找Outbound執(zhí)行,而鏈表中的順序為head->out1->out2->in1->in2->tail,所以會繼續(xù)執(zhí)行到out2、out1

核心最容易讓人誤解的點總結(jié):

1、ctx.writeAndFlush只會從當(dāng)前的handler位置開始,往前找outbound執(zhí)行

2、ctx.pipeline().writeAndFlush與ctx.channel().writeAndFlush會從tail的位置開始,往前找outbound執(zhí)行

相信你看到這里,基本能掌握channelHandlerContext調(diào)用與pipeline、channel調(diào)用的區(qū)別,但我敢肯定你只能記住3~5天就又忘記了;所以我再加一句記憶方法:

每次add一個channelHandler都會創(chuàng)建一個channelHandlerContext與之綁定,channelHandlerContext的作用就是管理它所關(guān)聯(lián)的channelHandler和在同一個pipeline中的其他channelHandler之間的交互,他是什么?他與某個channelHandler綁定,權(quán)利有限,只能從當(dāng)前他所綁定的channelHandler開始搞事情;
而pipeline與channel比較屌,可以指揮從頭或者尾開始搞。

注:channelRead以及channelActive等這些都會接著pipeline傳遞

參考:
一文搞懂Netty中Handler的執(zhí)行順序
ctx.close() 和 ctx.channel().close() 到底有何區(qū)別?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容