最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

《跟閃電俠學(xué)Netty》閱讀筆記 - ChannelHandler 生命周期

2023-08-24 14:40 作者:懶時(shí)小窩  | 我要投稿

Part1引言

本文主要介紹ChannelHandler當(dāng)中的ChannelInboundHandler。

Part2思維導(dǎo)圖

https://www.mubu.com/doc/1lK922R14Bl

《跟閃電俠學(xué)Netty》- ChannelHandler 生命周期.png

Part3LifeCycleTestHandler 案例

首先來(lái)看一下案例,LifeCycleTestHandlerTest 利用適配器 ChannelInboundHandlerAdapter 重寫(xiě),重寫(xiě)相關(guān)方法。

  • public void handlerAdded(ChannelHandlerContext ctx) throws Exception

  • public void channelRegistered(ChannelHandlerContext ctx) throws Exception

  • public void channelActive(ChannelHandlerContext ctx) throws Exception

  • public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception

  • public void channelReadComplete(ChannelHandlerContext ctx) throws Exception

  • public void channelInactive(ChannelHandlerContext ctx) throws Exception

  • public void channelUnregistered(ChannelHandlerContext ctx) throws Exception

  • public void handlerRemoved(ChannelHandlerContext ctx) throws Exception


/**
?*?測(cè)試netty?channelHandler?的生命周期
?*
?*?對(duì)應(yīng)的是?ChannelInboundHandlerAdapter
?*/

@Slf4j
public?class?LifeCycleTestHandlerTest?extends?ChannelInboundHandlerAdapter?{

????public?static?void?main(String[]?args)?{
????????ServerBootstrap?serverBootstrap?=?new?ServerBootstrap();

????????NioEventLoopGroup?boss?=?new?NioEventLoopGroup();
????????NioEventLoopGroup?worker?=?new?NioEventLoopGroup();

????????serverBootstrap
????????????????.group(boss,?worker)
????????????????.channel(NioServerSocketChannel.class)
????????????????.childHandler(new?ChannelInitializer<NioSocketChannel>()?
{
????????????????????@Override
????????????????????protected?void?initChannel(NioSocketChannel?ch)?throws?Exception?{
????????????????????????ch.pipeline().addLast(new?StringDecoder());
????????????????????????ch.pipeline().addLast(new?LifeCycleTestHandlerTest());

????????????????????}

????????????????})
????????????????.bind(8001);

????}

????@Override
????public?void?handlerAdded(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("邏輯處理器被添加?handlerAdded()?");
????????super.handlerAdded(ctx);
????}

????@Override
????public?void?channelRegistered(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("channel?綁定到線程?(NioEventLoop):channelRegistered()?");
????????super.channelRegistered(ctx);
????}

????@Override
????public?void?channelActive(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("channel?準(zhǔn)備就緒?channelActive()");
????????super.channelActive(ctx);
????}

????@Override
????public?void?channelReadComplete(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("channel?某次數(shù)據(jù)讀寫(xiě)完成?channelReadComplete()?");
????????super.channelReadComplete(ctx);
????}

????@Override
????public?void?channelRead(ChannelHandlerContext?ctx,?Object?msg)?throws?Exception?{
????????log.info("channel?有數(shù)據(jù)可讀?channelRead()?");
????????super.channelRead(ctx,?msg);
????}

????@Override
????public?void?channelInactive(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("channel?被關(guān)閉?channelInactive()");
????????super.channelInactive(ctx);
????}

????@Override
????public?void?channelUnregistered(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("channel取消線程?(NioEventLoop)?的綁定:channelUnregistered()?");
????????super.channelUnregistered(ctx);
????}

????@Override
????public?void?handlerRemoved(ChannelHandlerContext?ctx)?throws?Exception?{
????????log.info("邏輯處理器被刪除?handlerRemoved()?");
????????super.handlerRemoved(ctx);
????}
}

如果啟動(dòng)Client客戶端并且進(jìn)行連接,ChannelHanlder 的回調(diào)方法執(zhí)行順序如下:

  1. handlerAdded()

  2. channelRegistered()

  3. channelActive()

  4. channelRead()

  5. channelReadComplete()

1Channel連接方法回調(diào)

根據(jù)上面的執(zhí)行順序,這里補(bǔ)充介紹回調(diào)方法的含義。

  1. 邏輯處理器被添加:handlerAdded() ?

    檢測(cè)到新連接,調(diào)用ch.pipleLine(new LifeCycleTestHandlerTest()) 之后的回調(diào),表示當(dāng)前的Channel成功綁定一個(gè)邏輯處理器

  2. channel 綁定到線程 (NioEventLoop):channelRegistered() ?

    表示當(dāng)前Channel所有邏輯處理器和某個(gè)線程模型的線程綁定完成,比如綁定到NIO模型的NioEventLoop。此時(shí)會(huì)創(chuàng)建線程處理連接的讀寫(xiě),具體使用了JDK的線程池實(shí)現(xiàn),通過(guò)線程池抓一個(gè)線程方式綁定。

  3. channel 準(zhǔn)備就緒: channelActive()

    觸發(fā)條件是所有的業(yè)務(wù)邏輯準(zhǔn)備完成,也就是pipeline添加了所有的Handler ,以及綁定好一個(gè)NIO的線程之后,相當(dāng)于是worker全部就位,就等boss一聲令下開(kāi)工。

  4. channel 有數(shù)據(jù)可讀 channelRead()

    客戶端每次發(fā)數(shù)據(jù)都會(huì)以此進(jìn)行回調(diào)。

  5. channel 某次數(shù)據(jù)讀寫(xiě)完成 channelReadComplete()

    服務(wù)端每次處理以此數(shù)據(jù)都回調(diào)此方法進(jìn)行回調(diào) 。

Part4Channel 關(guān)閉方法回調(diào)

  1. channel 被關(guān)閉:channelInactive()

    TCP層已經(jīng)轉(zhuǎn)為非ESTABLISH模式。

  2. channel取消線程 (NioEventLoop) 的綁定:channelUnregistered()

    與連接線程的綁定全部取消時(shí)候觸發(fā)。

  3. 邏輯處理器被刪除:handlerRemoved()

    移除連接對(duì)應(yīng)的所有業(yè)務(wù)邏輯處理器觸發(fā)。

Part5Channel連接和關(guān)閉回調(diào)流程圖

Channel連接和關(guān)閉回調(diào)流程圖

Part6ChannelHanlder用法舉例

2ChannelInitializer

入門(mén)程序當(dāng)中的 .childHandler(new ChannelInitializer<NioSocketChannel>()定義了抽象initChannel方法,抽象方法需要自行實(shí)現(xiàn),通常是服務(wù)端啟動(dòng)流程的邏輯處理器中使用,添加Handler鏈到Pipeline。

handlerAdded() 方法和 channelRegistered()方法都會(huì)嘗試調(diào)用 initChannel,initChannel被多次調(diào)用,利用putIfAbsent防止initChannel被多次調(diào)用。

if?(initMap.putIfAbsent(ctx,?Boolean.TRUE)?==?null)?{?//?Guard?against?re-entrance.??

思考:為什么既要防止被多次調(diào)用,Netty又要調(diào)用多次initChannel
1. handlerAdded方法已經(jīng)通過(guò)Channel進(jìn)行綁定。 2. 用戶自行覆蓋和重寫(xiě)ChannelInitializerhandlerAdded,導(dǎo)致Channel不觸發(fā)綁定
3. channelRegisted() 中再觸發(fā)一次綁定,并且本身不允許被重寫(xiě)。
public final void channelRegistered(ChannelHandlerContext ctx) throws Exception {
4. 引導(dǎo)實(shí)現(xiàn)者只關(guān)注重寫(xiě)handlerAdded之后的邏輯處理

3handlerAdded 與 channelInActive

主要用做資源釋放和申請(qǐng)。

4channelActive 和 ChannelInActive

應(yīng)用的場(chǎng)景如下:

  1. TCP建立和連接抽象

  2. 實(shí)現(xiàn)統(tǒng)計(jì)單機(jī)的連接數(shù)量

    • 其中channelActive被調(diào)用,對(duì)應(yīng)的每次調(diào)用連接+1

    • 其中channelInActive被調(diào)用,對(duì)應(yīng)的每次調(diào)用連接-1

  3. 實(shí)現(xiàn)客戶端IP黑白名單的連接過(guò)濾

5channelRead()

這個(gè)方法和粘包和拆包問(wèn)題相關(guān),服務(wù)端根據(jù)自定義協(xié)議拆包,在這個(gè)方法中每次讀取一定數(shù)據(jù),都會(huì)累加到容器當(dāng)中。

6channelReadComplete

每次向客戶端寫(xiě)入數(shù)據(jù)都調(diào)用writeAndFlush不是很高效, ?更好的實(shí)現(xiàn)是向客戶端寫(xiě)數(shù)據(jù)只write,但是在ChannelReadComplete里面一次 flush ,所以這個(gè)方法相當(dāng)于批量刷新機(jī)制,批量刷新追求更高性能。

Part7總結(jié)

  1. 本部分主要是介紹ChannelHandler的各種回調(diào),以及連接建立關(guān)閉,執(zhí)行回調(diào)是一個(gè)逆向過(guò)程。

  2. 每一種回調(diào)都有各自用法,但是部分回調(diào)界限比較模糊,更多需要在實(shí)踐中區(qū)分和使用。

Part8寫(xiě)到最后

生命周期和回調(diào)在Netty中非常直觀,本文更多是對(duì)于重要的方法進(jìn)行羅列。


《跟閃電俠學(xué)Netty》閱讀筆記 - ChannelHandler 生命周期的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
吴桥县| 太仆寺旗| 辽宁省| 色达县| 淮北市| 永川市| 怀集县| 新竹市| 当涂县| 威信县| 黑水县| 罗定市| 邹平县| 友谊县| 探索| 浦东新区| 尼木县| 西贡区| 庆元县| 浮山县| 会同县| 嵩明县| 丹阳市| 宁晋县| 北宁市| 陆良县| 荥经县| 山东省| 武宁县| 博爱县| 昌宁县| 滕州市| 民县| 深泽县| 延安市| 徐闻县| 嘉鱼县| 佛坪县| 射阳县| 呈贡县| 乐业县|