windows环境下进入方法CTRL+🖱左键 回到上层方法CTRL+ALT+⬅
启动流程
- 创建服务端Channel
- 初始化服务端Channel
- 注册selector
- 端口绑定
创建服务端Channel
- 代码入口 ->bind()
- 注册并初始化 ->initAndRegister()
- 创建服务端channel ->newChannel()
此处通过反射创建channel,而传入的class就是NioServerSocketChannel.class
通过反射创建服务端Channel
- 通过jdk创建底层jdk channel ->newSocket()
- TCP参数配置类 ->new NioServerSocketChannelConfig()
- AbstractNioChannel中设置非阻塞configureBlocking、创建id、unsafe、pipeline
newSocket再深入就会看到导入的包为import java.nio.channels.*;
设置tcp参数类
![]()
![]()
设置非阻塞
![]()
设置id、unsafe、pipeline
初始化服务端channel
在上文newChannel()中通过反射创建channel之后,我们紧跟下一步
- 代码入口 ->init()
- set ChannelOptions和ChannelAttrs
- set ChildOptions和ChildAttrs
- 配置服务端pipeline
- 添加连接器 add ServerBootstrapAcceptor
设置ChannelOptions和ChannelAttrs
设置ChildOptions和ChildAttrs
向pipeline中添加用户自定义的handler,这里就是前文我们所写的Server Handler
![]()
紧接着添加自定义pipeline之后会添加一个特殊的handler->ServerBootstrapAcceptor
其中它的四个参数就是我们自定义的几个参数,currentChildGroup就是我们在Server类中所写的workGroup
注册selector
- 代码入口 ->AbstractChannel.register()
- 绑定线程 AbstractChannel.this.eventLoop = eventLoop
- 进行实际注册 ->register0()
- 调用jdk底层注册 ->doRegister()
- 传播事件 invokeHandlerAddedIfNeeded和fireChannelRegistered
首先我们再次进入initAndRegister方法,然后点击Channel接口找到它实际执行的register方法,从而来到AbstractChannel的register()
![]()
绑定线程
继而向下看进入register0方法,为实际注册doRegister()
![]()
![]()
![]()
看完注册之后,回到register0方法,可以看到在执行doRegister()方法之后又执行了两个传播事件,运行程序后会发现,它其实按照顺序执行就是我们自定义的server handler中重写的两个方法
![]()
端口绑定
- 代码入口 ->AbstractChannel.bind()
- dobind()
- jdk底层绑定 ->javaChannel().bind()
- fireChannelActive和readIfIsAutoRead
首先我们先进入之前分析initAndRegister那里,继注册初始化之后,进行端口绑定doBand0方法,而doband0方法会调用AbstractChannel下的Bind方法,因为AbstractChannel实现Channel接口,我们如上文查找register一样,点击Channel接口找到它实际执行的bing方法,从而来到AbstractChannel的bind()
在bind方法中可以看到doBind方法,我们点击进入选择NioSocketChannel,继而发现jdk底层绑定端口
在端口绑定完成之后会传播一个channelActive事件,进入之后找channelActive方法 fireChannelActive传播事件和前面那两个传播事件一样会执行serverhandler重写的方法,而readIfIsAutoRead则是表明绑定之后可以接收客户端了