亲宝软件园·资讯

展开

Netty分布式监听读事件

向南是个万人迷 人气:0

前文传送门:NioSocketChannel注册到selector

我们回到AbstractUnsafe的register0()方法:

private void register0(ChannelPromise promise) {
    try {
        //省略代码
        //做实际的注册
        doRegister();
        neverRegistered = false;
        registered = true;
        //触发事件
        pipeline.invokeHandlerAddedIfNeeded();
        safeSetSuccess(promise);
        //触发注册成功事件
        pipeline.fireChannelRegistered();
        if (isActive()) {
            if (firstRegistration) {
                //传播active事件(4)
                pipeline.fireChannelActive();
            } else if (config().isAutoRead()) {
                beginRead();
            }
        }
    } catch (Throwable t) {
        //省略代码
    }
}

doRegister()做完实际的注册之后, 会走到if (isActive())这个判断, 因为这个时候链路已经完成, 所以这里是true, 默认判断条件if (firstRegistration)也为true, 所以这里会走到pipeline.fireChannelActive()这一步

有关pipeline我们会在下一章进行详细分析, 这里我们只需要知道, 最后会流转到AbstractUnsafe的beginRead()方法

跟到beginRead()方法:

public final void beginRead() {
    assertEventLoop();
    if (!isActive()) {
        return;
    }
    try {
        doBeginRead();
    } catch (final Exception e) {
        //代码省略
    }
}

这块代码同样我们也不陌生, 因为我们分析NioServerSocketChannel也分析过了这一步

我们继续跟到doBeginRead():

protected void doBeginRead() throws Exception {
    //拿到selectionKey
    final SelectionKey selectionKey = this.selectionKey;
    if (!selectionKey.isValid()) {
        return;
    }
    readPending = true;
    //获得感兴趣的事件
    final int interestOps = selectionKey.interestOps();
    //判断是不是对任何事件都不监听
    if ((interestOps & readInterestOp) == 0) {
        //此条件成立
        //将之前的accept事件注册, readInterest代表可以读取一个新连接的意思
        selectionKey.interestOps(interestOps | readInterestOp);
    }
}

这段代码相信大家会比较熟悉, 因为我们服务端channel注册完之后也走到了这里

因为我们在创建NioSocketChannel的时候初始化的是read事件, selectionKey是channel在注册时候返回的key, 所以selectionKey.interestOps(interestOps | readInterestOp)这一步, 会将当前channel的读事件注册到selector中去

注册完成之后, NioEventLoop就可以轮询当前channel的读事件了

加载全部内容

相关教程
猜你喜欢
用户评论