新连接接入

入口

private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
        ...
        // 服务器收到Accept事件,来到这里准备新连接的处理
        if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
            unsafe.read();
            ...
        }
    ...
}

接下来开始接入新连接,read会将拿到的新连接存在本地的readBuf中。

public void read() {
    assert eventLoop().inEventLoop();
    final ChannelConfig config = config();
    final ChannelPipeline pipeline = pipeline();
    final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
    allocHandle.reset(config);

    boolean closed = false;
    Throwable exception = null;
    try {
        try {
            do {
                // doReadMessages拿底层accept的socketchannel
                // 将拿到的channel收集到本地readBuf
                int localRead = doReadMessages(readBuf);
                if (localRead == 0) {
                    break;
                }
                if (localRead < 0) {
                    closed = true;
                    break;
                }

                allocHandle.incMessagesRead(localRead);
                // 判断是否还可以继续接入新连接
            } while (allocHandle.continueReading());
        } catch (Throwable t) {
            exception = t;
        }

        int size = readBuf.size();
        // 遍历上面收集到的连接channel,逐个触发fireChannelRead
        // 而这里触发的pipeline的handler是服务端启动的时候默认加载的ServerBootstrapAcceptor
        for (int i = 0; i < size; i ++) {
            readPending = false;
            pipeline.fireChannelRead(readBuf.get(i));
        }
        readBuf.clear();
        allocHandle.readComplete();
        pipeline.fireChannelReadComplete();
        ...
    } finally {
       ...
    }
}

组装SocketChannel

protected int doReadMessages(List buf) throws Exception {
    // 拿到底层NIO的SocketChannel
    SocketChannel ch = javaChannel().accept();

    try {
        if (ch != null) {
            // 封装SocketChannel为Netty自定义的NioSocketChannel
            // 并将this也就是NioServerSocketChannel作为parent
            // 加到本地保存,并返回1,表示成功拿到
            buf.add(new NioSocketChannel(this, ch));
            return 1;
        }
    } catch (Throwable t) {
        ...
    }
    // 否则没有连接,返回0
    return 0;
}
 
 

Channel分类

1563634925318.png

NioSocketChannel结构

1563633366967.png

创建NioSocketChannel

public NioSocketChannel(Channel parent, SocketChannel socket) {
    super(parent, socket);
    config = new NioSocketChannelConfig(this, socket.socket());
}

AbstractNioByteChannel

protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {
    // 将OP_READ往上传,说明新连接建立后,服务器开始接收READ事件
    super(parent, ch, SelectionKey.OP_READ);
}

AbstractNioChannel

protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
    super(parent);
    // 保存NIO的SocketChannel
    this.ch = ch;
    // 保存READ事件码
    this.readInterestOp = readInterestOp;
    try {
        // 设置NIO非阻塞模式
        ch.configureBlocking(false);
    } catch (IOException e) {
       ...
    }
}

AbstractChannel

protected AbstractChannel(Channel parent) {
    // NioServerSocketChannel
    this.parent = parent;
    id = newId();
    unsafe = newUnsafe();
    pipeline = newChannelPipeline();
}

config

public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
    super(channel);
    if (javaSocket == null) {
        throw new NullPointerException("javaSocket");
    }
    this.javaSocket = javaSocket;

    // Enable TCP_NODELAY by default if possible.
    if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
        try {
            // 设置TcpNoDelay,不会攒包,有的话立即发送
            setTcpNoDelay(true);
        } catch (Exception e) {
            // Ignore.
        }
    }
}

ServerBootstrapAcceptor

fireChannelRead

public void channelRead(ChannelHandlerContext ctx, Object msg) {
    final Channel child = (Channel) msg;
    // childHandler添加到子连接的pipeline中,也就是ChannelInitializer
    // 这里作为pipeline的起手式,将该ChannelInitializer作为该pipeline的第一个执行者
    child.pipeline().addLast(childHandler);

    // 设置options到客户端channel的config
    for (Entry, Object> e: childOptions) {
        try {
            if (!child.config().setOption((ChannelOption) e.getKey(), e.getValue()))
            ...
        ...
    }

    // 设置attrs
    for (Entry, Object> e: childAttrs) {
        child.attr((AttributeKey) e.getKey()).set(e.getValue());
    }

    try {
        // 将NioSocketChannel注册到NioEventLoopGroup上的一个EventLoop上
        childGroup.register(child).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    forceClose(child, future.cause());
                }
            }
        });
    ...
}
 
 

register

public ChannelFuture register(Channel channel) {
    // next就是拿到下一个EventLoop,NioEventLoopGroup的chooser来滚动整个EventLoop数组
    // 继续往下探
    return next().register(channel);
}
public ChannelFuture register(Channel channel) {
    // 对channel进行简单封装成Promise
    return register(new DefaultChannelPromise(channel, this));
}
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
    ...
    AbstractChannel.this.eventLoop = eventLoop;

    // 当前是boss发起,那么这里必然进不去
    if (eventLoop.inEventLoop()) {
        register0(promise);
    } else {
        try {
            // 这里新建线程运行,并跟eventLoop绑定,之后就由该线程与channel进行互动
            eventLoop.execute(new Runnable() {
                @Override
                public void run() {
                    register0(promise);
                }
            });
        } catch (Throwable t) {
            ...
        }
    }
}
private void register0(ChannelPromise promise) {
    try {

        boolean firstRegistration = neverRegistered;
        doRegister();
        neverRegistered = false;
        registered = true;

        pipeline.invokeHandlerAddedIfNeeded();

        safeSetSuccess(promise);
        pipeline.fireChannelRegistered();
        
        if (isActive()) {
            if (firstRegistration) {
                pipeline.fireChannelActive();
            } else if (config().isAutoRead()) {
                ...
                beginRead();
            }
        }
    } catch (Throwable t) {
       ...
    }
}

doRegister

 protected void doRegister() throws Exception {
        boolean selected = false;
        for (;;) {
            try {
                // 终于看到NIO的调用,将selector与channel绑定
                // 至此底层注册完成
                selectionKey = javaChannel().register(eventLoop().selector, 0, this);
                return;
            } catch (CancelledKeyException e) {
                ...
            }
        }
    }

invokeHandlerAddedIfNeeded

final void invokeHandlerAddedIfNeeded() {
    assert channel.eventLoop().inEventLoop();
    if (firstRegistration) {
        firstRegistration = false;
        // 接着去调用callHandlerAddedForAllHandlers
        callHandlerAddedForAllHandlers();
    }
}
private void callHandlerAddedForAllHandlers() {
    final PendingHandlerCallback pendingHandlerCallbackHead;
    synchronized (this) {
        assert !registered;

        // This Channel itself was registered.
        registered = true;

        pendingHandlerCallbackHead = this.pendingHandlerCallbackHead;
        // Null out so it can be GC'ed.
        this.pendingHandlerCallbackHead = null;
    }
    
    // 那么这个pendingHandlerCallbackHead到底是哪里来的,要记得上面boss在fireChannelRead的时候会
    // addLast一个ChannelInitializer么?
    PendingHandlerCallback task = pendingHandlerCallbackHead;
    while (task != null) {
        // 那么这里的execute
        task.execute();
        task = task.next;
    }
}
ChannelInitializer
addLast
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) { 
    ...
    // 将ChannelInitializer保证成nexCtx
    newCtx = newContext(group, filterName(name, handler), handler);
    ...
    // 如果是客户端channel还没有注册到这个EventLoop上,调用callHandlerCallbackLater,将              // ChannelInitializer与pendingHandlerCallbackHead进行绑定
    // 实际上这个handler将作为客户端pipeline的head来处理,且初始化完成后会remove掉自己
    if (!registered) {
        newCtx.setAddPending();
        callHandlerCallbackLater(newCtx, true);
        return this;
    }
    ...
}
execute
void execute() {
    EventExecutor executor = ctx.executor();
    if (executor.inEventLoop()) {
        // 最终会调用callHandlerAdded0
        callHandlerAdded0(ctx);
    } else {
        try {
            executor.execute(this);
        } catch (RejectedExecutionException e) {
           ...
        }
    }
}
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        if (ctx.channel().isRegistered()) {
            // 会最终会执行Initializer的initChannel
            initChannel(ctx);
        }
    }
private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
    if (initMap.putIfAbsent(ctx, Boolean.TRUE) == null) { // Guard against re-entrance.
        try {
            // 这里真正开始执行用户自定义的Initializer的initChannel方法
            initChannel((C) ctx.channel());
        } catch (Throwable cause) {
           ...
        } finally {
            // 责任链初始化完成后会移除该Initializer,这样整个客户端pipeline的责任链初始化完成
            remove(ctx);
        }
        return true;
    }
    return false;
}

fireChannelRegistered

public ChannelHandlerContext fireChannelRegistered() {
    // 遍历pipeline的handler执行invokeChannelRegistered
    invokeChannelRegistered(findContextInbound());
    return this;
}
private AbstractChannelHandlerContext findContextInbound() {
    AbstractChannelHandlerContext ctx = this;
    do {
        // 拿到下一个handler
        ctx = ctx.next;
    } while (!ctx.inbound);
    return ctx;
}
private void invokeChannelRegistered() {
    if (invokeHandler()) {
        try {
            // 执行channelRegistered方法
            ((ChannelInboundHandler) handler()).channelRegistered(this);
        } catch (Throwable t) {
            notifyHandlerException(t);
        }
    } else {
        fireChannelRegistered();
    }
}

fireChannelActive

public void channelActive(ChannelHandlerContext ctx) throws Exception {
    // 将ChannelActive事件在pipeline上继续往后传播,也就是执行各个链上的channelActive方法
    ctx.fireChannelActive();
    // 开始正式read
    readIfIsAutoRead();
}
read
private void readIfIsAutoRead() {
    if (channel.config().isAutoRead()) {
        // 这里会在底层注册给selector注册通道的read事件
        channel.read();
    }
}
protected void doBeginRead() throws Exception {
    // Channel.read() or ChannelHandlerContext.read() was called
    final SelectionKey selectionKey = this.selectionKey;
    if (!selectionKey.isValid()) {
        return;
    }

    readPending = true;

    final int interestOps = selectionKey.interestOps();
    if ((interestOps & readInterestOp) == 0) {
        // 前面register的时候,没有注册任何事件,也就是0,这里开始注册read,说明前期准备工作已经完成
        // 可以正式开始接收客户端发来的数据了
        // 而这里的readInterestOp是创建NioSocketChannel的时候指定的OP_READ事件
        // NIO的代码,做ready注册
        selectionKey.interestOps(interestOps | readInterestOp);
    }
}

你可能感兴趣的:(新连接接入)