ServerBootstrapAcceptor
是Netty服务端用来接收客户端连接的核心类,本文将介绍ServerBootstrapAcceptor
的职能。
init
方法在上一篇文章源码解读 backlog 参数作用中我们知道,在Netty服务端启动时,会调用ServerBootstrap.bind()
绑定本地端口用来监听客户端的连接。
而这个方法会通过反射创建ServerSocketChannel
并初始化,ServerBootstrap.init()
会初始化ServerSocketChannel
,将ServerBootstrapAcceptor
添加到服务端Channel
的Pipeline
中。
init
方法用于服务端Channel的初始化,初始化ServerSocketChannel
的ChannelPipeline
,并向ChannelPipeline
中添加了一个ChannelInitializer
。
ChannelInitializer
是一个ChannelHandler
,但它不处理任何出站、入站事件,其目的只为了完成Channel
的初始化。
当ChannelHandler
被添加到ChannelPipeline
后,会触发一个handlerAdded
方法回调,这个方法里会调用initChannel()
进行初始化,初始化完成后会将自己从Pipeline
中删除,
We are done with init the Channel, removing the initializer now.(完成 Channel 的初始化后,删除初始化器。)
我们再看回ServerBootstrapAcceptor
类,其中在向ChannelPipeline
中添加ChannelInitializer
时,在initChannel
方法中会向ChannelPipeline
中添加一个ServerBootstrap.handler()
。这是个用户自定义的ChannelHandler
,如果用户没有设置,就不会通过判空校验,也就不会添加到ChannelPipeline
中。
在处理完用户自定义的ChannelHandler
后,还会再添加一个ServerBootstrapAcceptor
。
ServerBootstrapAcceptor
类我们先看一下ServerBootstrapAcceptor
类图结构(虚线表示实现接口,实线表示类继承),我们得知ServerBootstrapAcceptor
实现了ChannelInboundHandler
接口,而是ChannelInboundHandler
本身就是进站处理器,处理channel进站的一系列事件。
ServerBootstrapAcceptor
类属性也就是childChannel相关的配置信息,相关介绍如下:
ServerBootstrapAcceptor
类重写了channelRead
方法,这是它最主要的方法。
在channelRead
方法中,整个过程如下:
SocketChannel
的Pipeline
。ChannelOptions
和Attributes
。Channel
注册到WorkerGroup
中。Channel
注册到workGroup
中。如果整个过程出现了异常,Netty会调用forceClose()
强制关闭连接,其底层是调用了SocketChannel.close()
方法关闭连接。
channelRead
方法debug模式启动netty后,我们在channelRead
方法打断点,通过nc
连接netty服务端。
nc localhost 8888
运行nc指令后,我们会发现断点位置阻塞了。
我们可以看到,传入的msg是NioSocketChannel
,记录的是与客户端连接的channel。接下来我们仔细看一下调用栈,该方法被触发时是运行在bossGroup
的线程中的。
当有新客户端连接时,就会触发ServerBootstrapAcceptor
类的channelRead
方法。
ServerBootstrapAcceptor
类是一个特殊的ChannelHandler
,是Netty服务端用来接收客户端连接的核心类。
ServerBootstrap
在初始化Channel
时,会往它的ChannelPipeline
中添加ServerBootstrapAcceptor
,而ServerBootstrapAcceptor
重写了ChannelRead
回调,当有新客户端连接时,就会触发ChannelRead
回调,这样ServerBootstrapAcceptor
就可以拿到客户端连接,并对客户端连接进行初始化并注册到WorkerGroup
中。