Netty source code analysis (VII): acquaintance ChannelPipeline

ChannelPipelineJust look at the name can know Channelthe pipeline. This article deals combined with its default implementation class DefaultChannelPipelineto make it a simple introduction.

sample graph


The figure is provided by the official ChannelPipelinecase diagram. IO requests over ChannelOutboundHandlerthe ChannelOutboundHandlerwrite to the server after treatment, after receiving the service read by ChannelInboundHandlerthe processing sequence.
Look at the following DefaultChannelPipelineclass diagram:

DefaultChannelPipelineimplements ChannelPipelinean interface, and ChannelPipelinehas inherited ChannelInboundInvoker, ChannelOutboundInvokerand Iterable.
ChannelInboundInvoker: Launch of ChannelPipelinea next ChannelInboundHandlercall method.
ChannelOutboundInvoker: Launch of ChannelPipelinea next ChannelOutboundHandlercall method.
Iterable: It can be traversed ChannelPipelinein ChannelHandler.
NioEventLoopInherited from SingleThreadEventLoop, but SingleThreadEventLoopalso inherited from SingleThreadEventExecutor.
SingleThreadEventExecutorInternal holds a Thread object is the Nettybasis for multi-threaded.
It is believed that one NioEventLoopis bound to a specific thread, and during its life cycle, binding thread will not change.

DefaultChannelPipeline

DefaultChannelPipelineThe main job is to ChannelHandlermanage, including ChannelHandlerthe increase or decrease, triggering events and so on.

ChannelHandlerIncrease or decrease

In a addFirstmethod as an example:

    public final ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            // 检查handler是否可以共享
            checkMultiplicity(handler);
            // 给AbstractChannelHandlerContext起个独立的名字
            name = filterName(name, handler);
            // 创建DefaultChannelHandlerContext
            newCtx = newContext(group, name, handler);
            // 执行实际的添加操作
            addFirst0(newCtx);
            // channel尚未注册到eventloop
            if (!registered) {
                // 设置newCtx的状态为ADD_PENDING
                newCtx.setAddPending();
                // 设置过一会回调ChannelHandler的handlerAdded方法
                callHandlerCallbackLater(newCtx, true);
                return this;
            }
            EventExecutor executor = newCtx.executor();
            if (!executor.inEventLoop()) {
                newCtx.setAddPending();
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        callHandlerAdded0(newCtx);
                    }
                });
                return this;
            }
        }
        callHandlerAdded0(newCtx);
        return this;
    }

addFirst方法先检查添加的ChannelHandler是否可以共享(判断共享的方法是对于每个channel当前ChannelHandler是否需要不同的状态),再创建ChannelHandler的上下文关系,使ChannelHandler以链表方式存在于ChannelPipeline中。当ChannelHandler添加成功后,再调用ChannelHandlerhandlerAdded方法。其它的添加方式和addFirst类似。

事件触发

fireChannelActive方法为例:

    public final ChannelPipeline fireChannelActive() {
        AbstractChannelHandlerContext.invokeChannelActive(head);
        return this;
    }

HeadContext的head开始,依次触发下一个ChannelHandlerchannelActive方法。

本篇简单介绍了ChannelPipeline的相关概念,当ChannelHandler介绍完后,再具体介绍ChannelPipeline中的HeadContextTailContext

文中帖的代码注释全在:KAMIJYOUDOUMA, 有兴趣的童鞋可以关注一下。


本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!

Guess you like

Origin www.cnblogs.com/YJTZ/p/10994591.html