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ū)別?