Netty服务端启动过程总结
ServerBootstrap的bind()方法 -> AbstractBootstrap.doBind() :1. initAndRegister. 2. doBind0()
一、initAndRegister:
1. 初始化 NioServerSocketChannel : 初始化 ServerBootstrap 时 init(NioServerSocketChannel.class)
a. 调用 NioServerSocketChannel.newSocket(DEFAULT_SELECTOR_PROVIDER) 打开一个新的 Java NIO ServerSocketChannel
b. 在 AbstractChannel(Channel parent) 中初始化 AbstractChannel 的属性:
parent 属性置为 null
unsafe 通过 newUnsafe() 实例化一个 unsafe 对象
pipeline 是 new DefaultChannelPipeline(this) 新创建的实例
c. AbstractNioChannel 中的属性:
SelectableChannel ch 被设置为 Java ServerSocketChannel, 即 NioServerSocketChannel#newSocket 返回的 Java NIO ServerSocketChannel.
readInterestOp 被设置为 SelectionKey.OP_ACCEPT
SelectableChannel ch 被配置为非阻塞的 ch.configureBlocking(false)
d. NioServerSocketChannel 中的属性:
ServerSocketChannelConfig config = new NioServerSocketChannelConfig(this, javaChannel().socket())
2. init(): 调用 ServerBootstrap.init()
a. 将 handler 添加到 NioServerSocketChannel 的 pipeline ,此时还没有调用 handler.initChannel(), initChannel() 是由其他事件触发的!!!!!!!!!!!!!
b. 当 NioServerSocketChannel 完成 registered() 后会通过 fireChannelRegisted() 方法触发把 ServerBootstrapAcceptor 添加到 pipeLine 中
3. config().group().register(channel) -> AbstractChannel.register0(), 将 NioServerSocketChannel 和 BossGroup 中某个 eventLoop 的 Selector 关联,
fireChannelRegistered() 会触发 Handler 的 ChannelInitializer.initChannel()
a. doRegister() : 调用 AbstractNioChannel.doRegister() : selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
b. pipeline.fireChannelRegistered() -> 调用 ChannelInitializer.channelRegistered() -> ChannelInitializer.initChannel(), 将 ServerBootstrapAcceptor 添加到 NioServerSocketChannel 的 pipeline 中
c. 当有客户端连接后,触发 NioEventLoop 的 SelectionKey.OP_READ 事件,调用 AbstractNioChannel.NioUnsafe.read() -> ServerBootstrapAcceptor.channelRead()
. 有新的客户端连接请求时, channelRead() 负责新建此连接的 NioSocketChannel
. 添加 childHandler 到 NioSocketChannel 对应的 pipeline .
. 将此 NioSocketChannel 绑定到 workerGroup 中的某个 eventLoop 的 Selector 上.
二、doBind0() : 调用 AbstractChannel.bind() 将 NioServerSocketChannel 绑定到指定IP和端口,并注册 OP_ACCEPT 事件
1. doBind() -> NioServerSocketChannel.doBind() -> javaChannel().bind(localAddress, config.getBacklog());
2. pipeline.fireChannelActive() -> NioUnSafe.doBeginRead()->selectionKey.interestOps(interestOps | readInterestOp),此时服务端可以开始处理客户端的连接事件