Netty从入门到放弃,从放弃在到入门

Nio的好文章:https://zhuanlan.zhihu.com/p/64537916?utm_source=wechat_session&utm_medium=social&utm_oi=660405125986914304

 

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),此时服务端可以开始处理客户端的连接事件

posted @ 2020-02-25 11:47  不停的奋斗  阅读(245)  评论(0编辑  收藏  举报