Netty服务端源码阅读笔记(四)ServerBootstrap(2)

16 篇文章 0 订阅

接上章节 Netty服务端源码阅读笔记(四)ServerBootstrap(1)

serverBootStrap.bind() --> initAndRegister() --> init(channel);

serverBootStrap初始化NioServerSocketChannel

io.netty.bootstrap.ServerBootstrap#init

   void init(Channel channel) throws Exception {
        // 处理bootstrap中的option设置属性
        final Map<ChannelOption<?>, Object> options = options0();
        synchronized (options) {
            setChannelOptions(channel, options, logger);
        }

        // 处理bootstrap中的attr设置属性
        final Map<AttributeKey<?>, Object> attrs = attrs0();
        synchronized (attrs) {
            // 将bootstrap中设置的所有attr属性配置给channel
            for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
                @SuppressWarnings("unchecked")
                AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
                channel.attr(key).set(e.getValue());
            }
        }

        // 向pipeline中添加处理器,pipeline是DefaultChannelPipeline
        ChannelPipeline p = channel.pipeline();

        // 获取bootstrap中设置的所有child开头的属性
        final EventLoopGroup currentChildGroup = childGroup;
        final ChannelHandler currentChildHandler = childHandler;
        final Entry<ChannelOption<?>, Object>[] currentChildOptions;
        final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
        synchronized (childOptions) {
            currentChildOptions = childOptions.entrySet().toArray(newOptionArray(0));
        }
        synchronized (childAttrs) {
            currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(0));
        }

        // ChannelInitializer是一个处理器,其存在的意义是,为pipeline添加其它处理器
        p.addLast(new ChannelInitializer<Channel>() {
            @Override
            public void initChannel(final Channel ch) throws Exception {
                final ChannelPipeline pipeline = ch.pipeline();
                // 获取bootstrap中配置的handler()
                ChannelHandler handler = config.handler();
                if (handler != null) {
                    pipeline.addLast(handler);
                }

                // ch.eventLoop()是获取到当前channel所绑定的evenLoop
                // 然后再使用该eventLoop所绑定的线程来执行指定的任务
                ch.eventLoop().execute(new Runnable() {
                    @Override
                    public void run() {
                        // 向pipeline中添加ServerBootstrapAcceptor处理器
                        // 该处理器用于处理client的连接
                        pipeline.addLast(new ServerBootstrapAcceptor(
                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });
    }

主要来看看new pipelinepipeline.addLast加入handler时都怎么处理

pipeline是new NioServerSocketChannel()的时候初始化的,先看看DefaultChannelPipeline初始化new

    private PendingHandlerCallback pendingHandlerCallbackHead;// 一个PendingHandlerCallback的链表,PendingHandlerCallback是AbstractChannelHandlerContext的封装
    final AbstractChannelHandlerContext head;// 封装ChannelHandler的AbstractChannelHandlerContext 链表节点头
    final AbstractChannelHandlerContext tail;// 封装ChannelHandler的AbstractChannelHandlerContext 链表节点头
    private boolean firstRegistration = true;
    private boolean registered;

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

        tail = new TailContext(this);// 尾节点平平无奇
        head = new HeadContext(this);// 头节点大有作为

        head.next = tail;
        tail.prev = head;
    }

   final class TailContext extends AbstractChannelHandlerContext implements ChannelInboundHandler {
    // 内部实现了ChannelInboundHandler 中的各种方法,但是都是空实现
}

 大有作为的头节点,贴个代码,可以看到有bind和connect方法,且底层都是unsafe完成的,看到unsafe就知道比较nb,不往里边走了,bind()分在后篇看了,这里只是记下这个HeadContext很特殊就行

   final class HeadContext extends AbstractChannelHandlerContext
            implements ChannelOutboundHandler, ChannelInboundHandler {

        private final Unsafe unsafe;

        HeadContext(DefaultChannelPipeline pipeline) {
            super(pipeline, null, HEAD_NAME, HeadContext.class);

            // 底层操作对象,AbstractNioMessageChannel.NioMessageUnsafe对象
            // new channel中被创建
            unsafe = pipeline.channel().unsafe();
            setAddComplete();
        }
        @Override
        public ChannelHandler handler() {
            return this;
        }
        @Override
        public void bind(
                ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) {
            unsafe.bind(localAddress, promise);
        }
        @Override
        public void connect(
                ChannelHandlerContext ctx,
                SocketAddress remoteAddress, SocketAddress localAddress,
                ChannelPromise promise) {
            unsafe.connect(remoteAddress, localAddress, promise);
        }
    }

再看DefaultChannelPipeline#addLast(io.netty.channel.ChannelHandler...)

   @Override
    public final ChannelPipeline addLast(ChannelHandler... handlers) {
        return addLast(null, handlers);
    }

    @Override
    public final ChannelPipeline addLast(EventExecutorGroup executor, ChannelHandler... handlers) {
        if (handlers == null) {
            throw new NullPointerException("handlers");
        }

        for (ChannelHandler h: handlers) {
            if (h == null) {
                break;
            }
            addLast(executor, null, h);
        }

        return this;
    }

  public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            checkMultiplicity(handler);

            // 新建一个上边说过的链表节点,封装handler
            newCtx = newContext(group, filterName(name, handler), handler);

            // 给链表尾节点之前插一个newCtx,下边贴了代码
            addLast0(newCtx);
   
            if (!registered) {
                // 本文此时源码到这里,还未注册,刚到初始化channel不是

                // 设置一个标志位
                newCtx.setAddPending();
                
                // 把newCtx加入链表pendingHandlerCallbackHead,作为一个added任务,在注册的时候会依次调用这个链表中的handler
                callHandlerCallbackLater(newCtx, true);
                return this;
            }

            // 走到这就是,此时channel已经注册了
            // 那么就得调用这个新处理器的handlerAdded方法了,顾名思义,处理器添加回调嘛
            // 获取newCtx绑定的executor
            EventExecutor executor = newCtx.executor();

            // 当前线程不是executor内部绑定的线程则调用这个executor.execute执行handlerAdded
            if (!executor.inEventLoop()) {
                callHandlerAddedInEventLoop(newCtx, executor);
                return this;
            }
        }

        // 本线程调用次handler的handlerAdded方法
        callHandlerAdded0(newCtx);
        return this;
    }

// newCtx.executor();
//io.netty.channel.AbstractChannelHandlerContext#executor
// 这个executor是执行本handler的执行器,如果new时传入的group为空的话那么执行handler内部方法的线程就是channel绑定的eventloop,传入的话执行就由传入的执行器线程执行
    public EventExecutor executor() {
        if (executor == null) {
            return channel().eventLoop();
        } else {
            return executor;
        }
    }

    private void addLast0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext prev = tail.prev;
        newCtx.prev = prev;
        newCtx.next = tail;
        prev.next = newCtx;
        tail.prev = newCtx;
    }

   private void callHandlerCallbackLater(AbstractChannelHandlerContext ctx, boolean added) {
        assert !registered;

        PendingHandlerCallback task = added ? new PendingHandlerAddedTask(ctx) : new PendingHandlerRemovedTask(ctx);
        PendingHandlerCallback pending = pendingHandlerCallbackHead;
        if (pending == null) {
            pendingHandlerCallbackHead = task;
        } else {
            // Find the tail of the linked-list.
            while (pending.next != null) {
                pending = pending.next;
            }
            pending.next = task;
        }
    }

 newContext() 封装handler

    private AbstractChannelHandlerContext newContext(EventExecutorGroup group, String name, ChannelHandler handler) {
         // childExecutor(group)如果传入的group不为空,调用next()函数挑一个EventLoop绑定handler
        return new DefaultChannelHandlerContext(this, childExecutor(group), name, handler);
    }

  private final ChannelHandler handler;
    DefaultChannelHandlerContext(
            DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) {
        super(pipeline, executor, name, handler.getClass());
        this.handler = handler;
    }

   AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor executor,
                                  String name, Class<? extends ChannelHandler> handlerClass) {
        this.name = ObjectUtil.checkNotNull(name, "name");
        this.pipeline = pipeline;
        this.executor = executor;
        // mask标识这个handler实现了什么功能
        this.executionMask = mask(handlerClass);
        ordered = executor == null || executor instanceof OrderedEventExecutor;
    }

mask需要解释一下

ChannelHandler主要由两种组成,ChannelInboundHandler和ChannelOutboundHandler这两种,每种有很多实现方法,mask使用10101100这样子的int值来表示这个ChannelHandler具体实现了哪个方法

   static final int MASK_EXCEPTION_CAUGHT = 1;
    static final int MASK_CHANNEL_REGISTERED = 1 << 1;
    static final int MASK_CHANNEL_UNREGISTERED = 1 << 2;
    static final int MASK_CHANNEL_ACTIVE = 1 << 3;
    static final int MASK_CHANNEL_INACTIVE = 1 << 4;
    static final int MASK_CHANNEL_READ = 1 << 5;
    static final int MASK_CHANNEL_READ_COMPLETE = 1 << 6;
    static final int MASK_USER_EVENT_TRIGGERED = 1 << 7;
    static final int MASK_CHANNEL_WRITABILITY_CHANGED = 1 << 8;
    static final int MASK_BIND = 1 << 9;
    static final int MASK_CONNECT = 1 << 10;
    static final int MASK_DISCONNECT = 1 << 11;
    static final int MASK_CLOSE = 1 << 12;
    static final int MASK_DEREGISTER = 1 << 13;
    static final int MASK_READ = 1 << 14;
    static final int MASK_WRITE = 1 << 15;
    static final int MASK_FLUSH = 1 << 16;

    private static final int MASK_ALL_INBOUND = MASK_EXCEPTION_CAUGHT | MASK_CHANNEL_REGISTERED |
            MASK_CHANNEL_UNREGISTERED | MASK_CHANNEL_ACTIVE | MASK_CHANNEL_INACTIVE | MASK_CHANNEL_READ |
            MASK_CHANNEL_READ_COMPLETE | MASK_USER_EVENT_TRIGGERED | MASK_CHANNEL_WRITABILITY_CHANGED;
    private static final int MASK_ALL_OUTBOUND = MASK_EXCEPTION_CAUGHT | MASK_BIND | MASK_CONNECT | MASK_DISCONNECT |
            MASK_CLOSE | MASK_DEREGISTER | MASK_READ | MASK_WRITE | MASK_FLUSH;

    private static int mask0(Class<? extends ChannelHandler> handlerType) {
        int mask = MASK_EXCEPTION_CAUGHT;
        try {
            if (ChannelInboundHandler.class.isAssignableFrom(handlerType)) {
                mask |= MASK_ALL_INBOUND;
                // isSkippable方法判断此类是否实现了这个方法
                if (isSkippable(handlerType, "channelRegistered", ChannelHandlerContext.class)) {
                    mask &= ~MASK_CHANNEL_REGISTERED;
                }
                if (isSkippable(handlerType, "channelActive", ChannelHandlerContext.class)) {
                    mask &= ~MASK_CHANNEL_ACTIVE;
                }
。。。。。。。。
            }

            if (ChannelOutboundHandler.class.isAssignableFrom(handlerType)) {
                mask |= MASK_ALL_OUTBOUND;

                if (isSkippable(handlerType, "bind", ChannelHandlerContext.class,
                        SocketAddress.class, ChannelPromise.class)) {
                    mask &= ~MASK_BIND;
                }
                if (isSkippable(handlerType, "connect", ChannelHandlerContext.class, SocketAddress.class,
                        SocketAddress.class, ChannelPromise.class)) {
                    mask &= ~MASK_CONNECT;
                }
。。。。。。。。。。。。
            }

            if (isSkippable(handlerType, "exceptionCaught", ChannelHandlerContext.class, Throwable.class)) {
                mask &= ~MASK_EXCEPTION_CAUGHT;
            }
        } catch (Exception e) {
            // Should never reach here.
            PlatformDependent.throwException(e);
        }

        return mask;
    }

削微总结一下,再走一会就忘完了

初始化channel

一、先获取启动main方法中设置的.option、.attr等属性设置到channel上

二、1)为channel的pipeline设置ChannelInitializer初始化处理器,addLast方法中将handler封装为一个ChannelHandlerContext,放入链表供以后调用,ChannelHandlerContext中存在int mask标识实现的功能

       2)这个ChannelInitializer初始化处理器看起来是在注册channel的时候,调用绑定的eventLoop为channel.pipeline设置ServerBootstrapAcceptor处理器

此时基本就看完了初始化channel,但是还有个ServerBootstrapAcceptor是干什么的还没看

ServerBootstrapAcceptor处理器就是由childGroup和各种子group的属性创建

  private static class ServerBootstrapAcceptor extends ChannelInboundHandlerAdapter {

        private final EventLoopGroup childGroup;
        private final ChannelHandler childHandler;
        private final Entry<ChannelOption<?>, Object>[] childOptions;
        private final Entry<AttributeKey<?>, Object>[] childAttrs;
        private final Runnable enableAutoReadTask;

        ServerBootstrapAcceptor(
                final Channel channel, EventLoopGroup childGroup, ChannelHandler childHandler,
                Entry<ChannelOption<?>, Object>[] childOptions, Entry<AttributeKey<?>, Object>[] childAttrs) {
            this.childGroup = childGroup;
            this.childHandler = childHandler;
            this.childOptions = childOptions;
            this.childAttrs = childAttrs;
            enableAutoReadTask = new Runnable() {
                @Override
                public void run() {
                    channel.config().setAutoRead(true);
                }
            };
        }

        // 当client发送来连接请求时,会触发channelRead()方法的执行,初始化这个channel并注册监听读事件到selector
        @Override
        @SuppressWarnings("unchecked")
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            // 注意,这里client发送来的就是连接当前Server的子channel
            final Channel child = (Channel) msg;

            // 初始化这个子channel,这个childHandler是main方法中自定义的客户端请求处理器
            child.pipeline().addLast(childHandler);

            setChannelOptions(child, childOptions, logger);

            for (Entry<AttributeKey<?>, Object> e: childAttrs) {
                child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
            }

            try {
                // 将当前子channel注册到selector
                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);
            }
        }

到这就完事了,服务端channel中的ServerBootstrapAcceptor处理器当客户端连接请求过来,进入处理器的channelRead方法,内部初始化子channel,并设置自定义处理器,注册到childGroup中的selector中

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值