美文网首页
Channel Register

Channel Register

作者: huiwq1990 | 来源:发表于2017-07-28 17:32 被阅读0次
    image.png

    io.netty.channel.AbstractChannel.AbstractUnsafe#register

    开始注册

       if (eventLoop.inEventLoop()) {
                    register0(promise);
                } else {
                    try {
                        eventLoop.execute(new Runnable() {
                            @Override
                            public void run() {
                                register0(promise);
                            }
                        });
                    } catch (Throwable t) {
                    }
                }
    

    进入 io.netty.util.concurrent.SingleThreadEventExecutor#execute,SingleThreadEventExecutor重写线程池的execute方法

    1. 添加register0到任务队列
    2. 会调用线程start

    inEventLoop()方法用来判断当前是否在EventLoop线程执行,注册的时候是在main线程执行的,所以为false。

    eventLoop.execute

        @Override
        public void execute(Runnable task) {
            if (task == null) {
                throw new NullPointerException("task");
            }
    
            boolean inEventLoop = inEventLoop();
            if (inEventLoop) {
                addTask(task);
            } else {
                startThread();
                addTask(task);
                if (isShutdown() && removeTask(task)) {
                    reject();
                }
            }
    
            if (!addTaskWakesUp && wakesUpForTask(task)) {
                wakeup(inEventLoop);
            }
        }
    

    register0

    断点 io.netty.channel.AbstractChannel.AbstractUnsafe#register0
    SingleThreadEventExecutor的Thread运行的是NioEventLoop的run。

    image.png
      doRegister();
    pipeline.invokeHandlerAddedIfNeeded();
     pipeline.fireChannelRegistered();
    

    doRegister 会绑定channel到selector

    invokeHandlerAddedIfNeeded

    断点 ServerBootstrap 181
    断点 SimpleServerHandler#handlerAdded
    断点 ServerBootstrap 193

     p.addLast(new ChannelInitializer<Channel>() {
                @Override
                public void initChannel(Channel ch) throws Exception {
                    final ChannelPipeline pipeline = ch.pipeline();
                    ChannelHandler handler = handler();
                    if (handler != null) {
                        pipeline.addLast(handler);//断点
                    }
    
                    ch.eventLoop().execute(new Runnable() {
                        @Override
                        public void run() {
                            pipeline.addLast(new ServerBootstrapAcceptor(
                                    currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                        }
                    });
                }
            });
    

    调用pipeline.addLast(handler);之前,pipeline中只有head ServerBootstrap$1#0 tail
    调用之后,pipeline中有 head ServerBootstrap$1#0 SimpleServerHandler tail
    函数返回后,进入
    io.netty.channel.ChannelInitializer#initChannel(io.netty.channel.ChannelHandlerContext)

    if (initMap.putIfAbsent(ctx, Boolean.TRUE) == null) { // Guard against re-entrance.
                try {
                    initChannel((C) ctx.channel());
                } catch (Throwable cause) {
                    // Explicitly call exceptionCaught(...) as we removed the handler before calling initChannel(...).
                    // We do so to prevent multiple calls to initChannel(...).
                    exceptionCaught(ctx, cause);
                } finally {
                    remove(ctx);
                }
                return true;
            }
    

    然后会把ServerBootstrap$1#0删除。

    另外,对于pipeline添加ServerBootstrapAcceptor,会以任务方式提交到队列。

    image.png

    fireChannelRegistered

    SimpleServerHandler#channelRegistered

    相关文章

      网友评论

          本文标题:Channel Register

          本文链接:https://www.haomeiwen.com/subject/igmgkxtx.html