NOTE

2.72 3.注册selector

调用 bind - doBind - initAndRegister - channelFactory.newChannel() - init(channel) - ChannelFuture regFuture = config().group().register(channel);我们重点看这

Java创建于 更新于 historical

这是历史学习笔记,可能存在过时或不完整的理解。

调用

bind

  • doBind
  • initAndRegister
    • channelFactory.newChannel()
    • init(channel)
    • ChannelFuture regFuture = config().group().register(channel);我们重点看这个

在register上打个断点,最终经过的调用栈 io.netty.channel.MultithreadEventLoopGroup#register(io.netty.channel.Channel) io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.Channel) io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.ChannelPromise) io.netty.channel.AbstractChannel.AbstractUnsafe#register

public final void register(EventLoop eventLoop, final ChannelPromise promise) {
    if (eventLoop == null) {
        throw new NullPointerException("eventLoop");
    }
    if (isRegistered()) {
        promise.setFailure(new IllegalStateException("registered to an event loop already"));
        return;
    }
    if (!isCompatible(eventLoop)) {
        promise.setFailure(
                new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
        return;
    }
	//将eventLoop关联到此channel,之后channel的所有操作都是通过eventLoop
    AbstractChannel.this.eventLoop = eventLoop;

    if (eventLoop.inEventLoop()) {
        register0(promise);//实际注册
    } else {
        try {
            eventLoop.execute(new Runnable() {
                @Override
                public void run() {
                    register0(promise);
                }
            });
        } catch (Throwable t) {
            logger.warn(
                    "Force-closing a channel whose registration task was not accepted by an event loop: {}",
                    AbstractChannel.this, t);
            closeForcibly();
            closeFuture.setClosed();
            safeSetFailure(promise, t);
        }
    }
}
  • register0
doRegister();//调用jdk底层注册io.netty.channel.nio.AbstractNioChannel#doRegister

pipeline.invokeHandlerAddedIfNeeded();

//调用channelhandler的channelRegistered方法
pipeline.fireChannelRegistered();