netty学习6:ServerBootstrapAcceptor源码分析

借用网络上一张netty流程图 而我们今天要分析的ServerBootstrapAcceptor功能就是红色标注的这一块:netty是如何将bossGroup中接收到的SocketChannel注册到workerGroup的Selector之上。

ServerBootstrapAcceptor在io.netty.bootstrap.AbstractBootstrap#bind(int)方法,具体在io.netty.bootstrap.ServerBootstrap#init方法中,被添加到了bossGroup中的pipeline中

//初始化
void init(Channel channel) {//channel 是NioServerSocketChannel
        setChannelOptions(channel, newOptionsArray(), logger);
        setAttributes(channel, newAttributesArray());

        ChannelPipeline p = channel.pipeline();//pipeline在调用构造函数时候创建即DefaultChannelPipeline pipeline即handler组成的责任链

        final EventLoopGroup currentChildGroup = childGroup;//childGroup即workGroup
        final ChannelHandler currentChildHandler = childHandler;//childHandler即main方法里面childHandler设置的Handler处理器
        final Entry<ChannelOption<?>, Object>[] currentChildOptions = newOptionsArray(childOptions);//childOptions设置的属性
        final Entry<AttributeKey<?>, Object>[] currentChildAttrs = newAttributesArray(childAttrs);//childAttr设置的属性
        //pipeline即链表组成的责任链 addlast即添加到链表尾部  initChannel等待回调
        p.addLast(new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(final Channel ch) {
                final ChannelPipeline pipeline = ch.pipeline();//ch还是NioSeverSocketChannel
                ChannelHandler handler = config.handler();
                if (handler != null) {
                    pipeline.addLast(handler);
                }

                //netty重写了execute方法 io.netty.util.concurrent.SingleThreadEventExecutor.execute(java.lang.Runnable)
                // 这时做了两件事:1.添加任务队列到taskQueue,BossGroup线程自旋然后再处理taskQueue的run方法 也就是在bossGroup的线程中 执行的run方法并将ServerBootstrapAcceptor添加到pipeline当中 等待后续回调
                ch.eventLoop().execute(new Runnable() {
                    @Override
                    public void run() {
                        //异步往pipeline中添加新的handler 在创建ServerBootstrapAcceptor对象时候  传入了childGroup以及childHandler等等参数
                        pipeline.addLast(new ServerBootstrapAcceptor(
                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });
    }

 再创建ServerBootstrapAcceptor对象时候 传入了childGroup以及childHandler等等参数,这些参数我们在启动netty时候会设置

io.netty.bootstrap.ServerBootstrap.ServerBootstrapAcceptor#channelRead方法我们知道 在bossGroup的线程自旋时回调,然后通过EventExecutorChooser对象获取到下一个workGroup中的线程,启动workGroup线程,并将SocketChannel注册到workerGroup的selector并监听相关读事件

 public void channelRead(ChannelHandlerContext ctx, Object msg) {
            //NioSocketChannel也就是客户端的channel都注册到workGroup上
            final Channel child = (Channel) msg;
            //给workGroup的popeline 添加处理handler  childHandler是main方法里面添加
            child.pipeline().addLast(childHandler);

            setChannelOptions(child, childOptions, logger);
            setAttributes(child, childAttrs);

            try {
                //注册channel 并添加监听器  着重看register方法
                childGroup.register(child).addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        if (!future.isSuccess()) {
                            forceClose(child, future.cause());
                        }
                    }
                });
            } catch (Throwable t) {
                forceClose(child, t);
            }
        }

io.netty.channel.MultithreadEventLoopGroup#register(io.netty.channel.Channel)

通过Chooser获取到下一个执行任务的workerGroup线程

public ChannelFuture register(Channel channel) {
        return next().register(channel);//调用io.netty.channel.SingleThreadEventLoop.register(io.netty.channel.Channel)
    }

io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.Channel)

public ChannelFuture register(Channel channel) {
        //1.创建DefaultChannelPromise的对象 DefaultChannelPromise即可以操作返回结果的future对象
        //2。调用register方法
        return register(new DefaultChannelPromise(channel, this));
    }

public ChannelFuture register(final ChannelPromise promise) {
        ObjectUtil.checkNotNull(promise, "promise");
        promise.channel().unsafe().register(this, promise);//通过unsafe对象调用register方法
        return promise;
    }

io.netty.channel.AbstractChannel.AbstractUnsafe#register 进入了register方法 前面文章已经分析过register方法,也就是拿到了BossGroup中拿到的客户端SocketChannel注册到worker线程的Selector上

bossGroup、workerGroup线程又是如何自旋 如何执行对应的任务呢 这都是在io.netty.channel.nio.NioEventLoop中执行的 接下来会分析到

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值