在服务端启动后,便可以接受客户端连接。在服务端构造一套Reactor模式的工作线程模型。
这个图展示了接受客户端连接处理过程:服务端Pipeline的ServerBootstrapAccptor在接受连接,创建客户端通道NioSocketChannel,及其Pipeline的添加过程。当然在这个过程中也会把NioSocketChannel注册到Selector选择器并启动NioEventLoop工作线程。
github测试代码
NioEventLoop#run
1、NioEventLoop#run
io.netty.channel.nio.NioEventLoop#run
run方法内接受连接,这里还是服务端处理过程
2、processSelectedKeys
io.netty.channel.nio.NioEventLoop#processSelectedKeys
3、processSelectedKeysOptimized
io.netty.channel.nio.NioEventLoop#processSelectedKeysOptimized
OP_READ = 1 << 0 = 1
OP_WRITE = 1 << 2 = 4
OP_CONNECT = 1 << 3 = 8
OP_ACCEPT = 1 << 4 = 16
4、processSelectedKey
io.netty.channel.nio.NioEventLoop#processSelectedKey
首先获取NioUnsafe对象,此时是服务端处理所以
unsafe = AbstractNioMessageChannelHeadContext
msg = NioSocketChannel
8、invokeChannelRead
io.netty.channel.AbstractChannelHandlerContext#invokeChannelRead
9、channelRead
io.netty.channel.DefaultChannelPipeline.HeadContext#channelRead
从头结点向下传播执行channelRead方法
10、findContextInbound
io.netty.channel.AbstractChannelHandlerContext#findContextInbound
11、invokeChannelRead
io.netty.channel.AbstractChannelHandlerContext#invokeChannelRead
NioSocketChannel客户端通道处理
io.netty.bootstrap.ServerBootstrap.ServerBootstrapAcceptor#channelRead
当前的Channel对象是,客户端连接后生成的NioSocketChannel对象。
把childHandler(自定义的通过serverBootstrap.childHandler()方法添加的)添加到NioSocketChannel的pipeline队列中
NioSocketChannel设置Options和childAttrs参数
把当前NioSocketChannel注册到childGroup(就是workGroup)
io.netty.channel.AbstractChannel.AbstractUnsafe#register
所谓的Channel注册NioEventLoop就是调用register0方法
服务端和客户端Channel、unsafe对比
服务端Channel是NioServerSocketChannel,客户端是NioSocketChannel
服务端unsafe是NioMessageUnsafe,客户端的是NioByteUnsafe
接下来的调用与服务端启动类似就是开启NioEventLoop的Reactor工作线程进行传输数据
总结:
接受客户端连接主要步骤:
1、生成的客户端通道NioSocketChannel及其他初始化参数与服务端初始化类似
2、服务端的ServerBootstrapAccptor对象对NioSocketChannel的ChannelPipeline添加及其他参数的添加
3、NioSocketChannel注册到Selector并启动Reactor工作线程