Netty网络编程-服务端启动问题总结
1、Netty ServerSocktChannel是如何初始化和注册的
-
获取NioServerSocketChannel的实例,构造方法中还会做以下操作:
-
- 通过SelectorProvider获取ServerSocketChannel。
- 设置ServerSocketChannel为非阻塞。
- 为此Channel生成内部唯一Id。
- 初始化Netty内部Unsafe类实例。
- 初始化ChannelPipeline实例。
- 初始化ServerSocketChannelConfig实例。
-
初始化NioServerSocketChannel的属性
-
- 设置NioServerSocketChannel的Option
- 设置NioServerSocketChannel的Attribute,使用的是netty自封装的AttributeMap
- 设置NioServerSocketChannel属性ChannelPipeline的ChannelHandler,自定义的Handler
- 设置NioServerSocketChannel属性ChannelPipeline的ChannelHandler,添加ServerBootstrapAcceptor
-
NioServerSocketChannel注册到选择器上
-
- bossGroup中的每个NioEventLoop都有一个selector
- 获取bossGroup其中的一个NioEventLoop将此channel注册到选择器
2、Netty如何处理客户端连接
NioServerSocketChannel是注册到bossGroup中的一个NioEventLoop上的。NioEventLoop会轮训Selector获取事件,根据设置的感兴趣的事件做出相应的处理。例如连接事件。
- 轮训注册在其上的 ServerSocketChannel 的 accept 事件(OP_ACCEPT 事件)
- 处理 accept 事件,与客户端建立连接,生成一个 NioSocketChannel,并将其注册到WorkerGroup 中某个线程上的 Selector 上
- 再去以此循环处理任务队列中的下一个事件
3、ChannelPipeline中的Handler是何时初始化
NioServerSocketChannel中的ChannelPipeline初始化是在NioServerSocketChannel注册到bossGroup时触发的。
NioSocketChannel的ChannelPipeline初始化是在NioServerSocketChannel注册到childGroup时触发的。
因为首先ChannelPipeline使用的ChannelInitializer添加,所以触发注册事件首先会走到ChannelInitializer.channelRegistered方法,此方法会初始化ChannelPipeline定义的handler,结束后ChannelPipeline将移除自定义的ChannelInitializer实例。
4、ChannelPipeline中的Handler为什么要New而不能使用同一个实例
不使用@ChannelHandler.Sharable注解,Handler是无法在多个NioSocketChannel中共享的。
5、Netty如何将accept的连接交给childGroup
初始化NioServerSocketChannel的属性时,设置了NioServerSocketChannel的ServerBootstrapAcceptor,这是个handler,连接入站会处理连接,并分发到childGroup