真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

什么是Netty事件傳播

本篇內(nèi)容主要講解“什么是Netty事件傳播”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“什么是Netty事件傳播”吧!

成都創(chuàng)新互聯(lián)公司從2013年開始,先為和碩等服務(wù)建站,和碩等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為和碩企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

Netty高性能的背后,蘊(yùn)含著優(yōu)秀的設(shè)計(jì)。 今天我們從源碼角度詳細(xì)介紹Netty中ChannelPipeline的事件,以及這些事件是如何在ChannelPipeline中傳播的。

ChannelPipeline

ChannelPipeline是負(fù)責(zé)管理ChannelHandler的有序容器。 其內(nèi)部維護(hù)著一個(gè)由ChannelHandlerContext做為節(jié)點(diǎn)的雙向鏈表。 Netty上的事件便是通過(guò)這個(gè)鏈表進(jìn)行傳播的。

一圖勝千言

什么是Netty事件傳播

ChannelPipeline需要注意以下幾個(gè)關(guān)鍵點(diǎn):

  • Netty事件分為入站事件(inbound_event)和出站事件(outbound_event),入站事件由 InboundHandler 處理,出站事件由 OutboundHandler 處理。

  • 事件通過(guò)ChannelHandlerContext進(jìn)行傳播,入站事件順序傳播,出站事件逆序傳播。

  • 事件是顯示觸發(fā)的。(handler處理事件后,若要傳遞給下一個(gè)handler,必須顯示調(diào)用ChannelHandlerContext里的方法)

其中, 入站事件包括:

  • firefireChannelRegistered

  • fireChannelUnregistered

  • fireChannelActive

  • fireChannelInactive

  • fireChannelRead

  • fireChannelReadComplete

  • fireUserEventTriggered

  • fireChannelWritabilityChanged

  • fireExceptionCaught

出站事件包括:

  • bind

  • connect

  • disconnect

  • close

  • deregister

  • read

  • write

  • flush

  • writeAndFlush

handler里可以觸發(fā)任意的事件,即在InboundHandler里可以觸發(fā)出站事件,而OutboundHandler里也可以觸發(fā)入站事件。但注意不要出現(xiàn)事件的死循環(huán)。

更進(jìn)一步的,我們從源碼上去解讀ChannelPipeline的幾個(gè)要點(diǎn):

  • ChannelPipeline實(shí)例化后便提供了一個(gè)頭節(jié)點(diǎn)和一個(gè)尾節(jié)點(diǎn)的雙向鏈表。

    protected DefaultChannelPipeline(Channel channel) {
        this.channel = ObjectUtil.checkNotNull(channel, "channel");
        succeededFuture = new SucceededChannelFuture(channel, null);
        voidPromise =  new VoidChannelPromise(channel, true);

        tail = new TailContext(this);   //尾節(jié)點(diǎn)
        head = new HeadContext(this);   //頭節(jié)點(diǎn)

        // 通過(guò)前驅(qū)與后續(xù)引用,形成一個(gè)雙向鏈表
        head.next = tail;
        tail.prev = head;
    }
  • 頭節(jié)點(diǎn)被標(biāo)記為outbound和inboud,尾節(jié)點(diǎn)標(biāo)記為inboud。(在下面的ChannelHandlerContext會(huì)介紹其作用)

  • 頭節(jié)點(diǎn)的入站處理程序會(huì)觸發(fā)新的入站事件,出站處理程序會(huì)調(diào)用unsafe對(duì)象的操作(將數(shù)據(jù)輸出到Sokect)。

  • 尾節(jié)點(diǎn)的入站處理程序是空處理或回收資源操作,出站處理程序觸發(fā)新的出站事件。

    HeadContext(DefaultChannelPipeline pipeline) {
        super(pipeline, null, HEAD_NAME, true, true);   // outbound=true
        unsafe = pipeline.channel().unsafe();   // 出站事件傳播到了頭節(jié)點(diǎn)后,便調(diào)用該unsafe對(duì)象上的方法
        setAddComplete();
    }

    TailContext(DefaultChannelPipeline pipeline) {
        super(pipeline, null, TAIL_NAME, true, false);  // inboud=true
        setAddComplete();
    }

    protected void onUnhandledInboundMessage(Object msg) {
        try {
            logger.debug(
                    "Discarded inbound message {} that reached at the tail of the pipeline. " +
                            "Please check your pipeline configuration.", msg);
        } finally {
            ReferenceCountUtil.release(msg);    // 釋放引用,當(dāng)引用為0時(shí),便可回收內(nèi)存空間
        }
    }

    protected void onUnhandledInboundChannelReadComplete() {    // 空處理
    }

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        unsafe.write(msg, promise);     // 通過(guò)unsafe將數(shù)據(jù)輸出
    }
  • 在Channel和ChannelPineline上的事件會(huì)傳遞給頭節(jié)點(diǎn)(入站)或尾節(jié)點(diǎn)(出站)。(再配合其他節(jié)點(diǎn)的handler,就可以形成了從頭到尾(或從尾到頭)依次傳播的事件)

    @Override
    public final ChannelPipeline fireChannelActive() {
        AbstractChannelHandlerContext.invokeChannelActive(head); //觸發(fā)head節(jié)點(diǎn)入站事件
        return this;
    }

    @Override
    public final ChannelFuture writeAndFlush(Object msg) {
        return tail.writeAndFlush(msg); // 觸發(fā)tail節(jié)點(diǎn)出站事件
    }
  • addXXX(ChannelHandler)會(huì)實(shí)例化一個(gè)含handler的ChannelHandlerContext對(duì)象,并插入鏈表。

  • addFirst在頭節(jié)點(diǎn)后插入新節(jié)點(diǎn),addLass在尾節(jié)點(diǎn)前插入新節(jié)點(diǎn)。

private AbstractChannelHandlerContext newContext(EventExecutorGroup group, String name, ChannelHandler handler) {
        return new DefaultChannelHandlerContext(this, childExecutor(group), name, handler); // 實(shí)例化含handler的ChannelHandlerContext對(duì)象
    }

    private void addFirst0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext nextCtx = head.next;
        newCtx.prev = head;
        newCtx.next = nextCtx;
        head.next = newCtx;     // 新節(jié)點(diǎn)插入頭結(jié)點(diǎn)后面
        nextCtx.prev = newCtx;
    }

    private void addLast0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext prev = tail.prev;
        newCtx.prev = prev;
        newCtx.next = tail;
        prev.next = newCtx;
        tail.prev = newCtx;     // 新節(jié)點(diǎn)插入尾節(jié)點(diǎn)前面
    }

ChannelHandlerContext

ChannelHandlerContext是ChannelPipeline雙向鏈表中的節(jié)點(diǎn)。 它是連接ChannelHandler和ChannelPipeline的橋梁。有了它ChannelHandler才有機(jī)會(huì)響應(yīng)并處理ChannelPipeline中的事件。

其源碼不復(fù)雜,其中ChannelHandlerContext的findContextInbound/findContextOutbound 是實(shí)現(xiàn)入站事件傳遞給InboundHandler,出站事件傳遞給OutboundHandler的關(guān)鍵。 其實(shí)現(xiàn)也比較簡(jiǎn)單,就是判斷context的后續(xù)(入站事件)/前驅(qū)(出站事件)節(jié)點(diǎn)對(duì)應(yīng)的handler實(shí)現(xiàn)是否是inbound/outbound,如果不是則遍歷下一個(gè)節(jié)點(diǎn),直至尾節(jié)點(diǎn)/頭節(jié)點(diǎn)。

而在上面的分析中,我們已經(jīng)知道尾節(jié)點(diǎn)實(shí)例化時(shí),inbound被設(shè)置為ture,頭節(jié)點(diǎn)實(shí)例化時(shí),outbound被設(shè)置為ture。 這便形成的遍歷的終止條件。

    private AbstractChannelHandlerContext findContextInbound() {
        AbstractChannelHandlerContext ctx = this;
        do {
            ctx = ctx.next;
        } while (!ctx.inbound); //直到尾節(jié)點(diǎn),因?yàn)槲补?jié)點(diǎn)inbound在Pipeline中被定義為Ture
        return ctx;
    }

    private AbstractChannelHandlerContext findContextOutbound() {
        AbstractChannelHandlerContext ctx = this;
        do {
            ctx = ctx.prev;
        } while (!ctx.outbound);//直到頭節(jié)點(diǎn),因?yàn)轭^節(jié)點(diǎn)outbound在Pipeline中被定義為Ture
        return ctx;
    }

正是由于Netty這些優(yōu)秀的設(shè)計(jì),才使得其高性能下,仍然被靈活使用。 因此也被大家所接受并深愛著。


到此,相信大家對(duì)“什么是Netty事件傳播”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!


網(wǎng)頁(yè)標(biāo)題:什么是Netty事件傳播
網(wǎng)站地址:http://weahome.cn/article/gojcho.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部