===== 服务端 =====
- 初始化NioServerSocketChannel
- 初始化NioServerSocketChannel.pipeline。在pipeline中初始化一个 ChannelInitializer任务:任务内容
- 当NioServerSocketChannel注册完成时,为pipeline添加handler(注意不是childHandler)
- 当NioServerSocketChannel注册完成时,为pipeline添加ServerBootstrapAcceptor (用于处理接受用户连接)
- 当NioServerSocketChannel注册完成后,从pipeline上删除ChannelInitializer任务本身。
- 将NioServerSocketChannel 注册到boss中一个NioEventLoop上,生成NioServerSocketChannel.selectionKey
- 绑定ip和端口
- 设置NioServerSocketChannel.selectionKey 的interestOps = 16 (只关注Accept请求)
- 相关代码:pipeline.fireChannelActive()
- ==
- 客户端连接过来
- ==
- 上面ServerBootstrapAcceptor这个handler来处理用户的连接操作
- 初始化NioSocketChannel
- 初始化NioSocketChannel.pipeline。增加用户自定义的childHandler
- 将NioSocketChannel注册到到work中一个NioEventLoop上
- 置NioSocketChannel.selectionKey 的interestOps = 1 (只关Read请求)
- 相关代码:pipeline.fireChannelActive()
===== 客户端 =====
- 初始化NioSocketChannel
- 初始化NioSocketChannel.pipeline。增加用户自定义的childHandler
- 将NioSocketChannel注册到到work中一个NioEventLoop上
- 连接到远程服务端的ip和端口,等待服务端接收连接
- 客户端设置interestOps = SelectionKey.CONNECT ,开始监听服务端接受连接的消息
- 服务端接受连接,客户端收到SelectionKey.CONNECT消息
- 客户端设置interestOps = SelectionKey.OP_READ, 开始监听服务端发来的数据
===== 额外的细节 =====
* selector 接收消息,NioSocketChannel中的unsafe处理数据,交给NioSocketChannel.pipeline处理
* 先由HeadContext处理
* 然后是自定义的hander
* 最后是TailContext
* 中途可以打断handler调用链条,上游的hander不调用ctx.fireChannelRead(msg); 就不会触发下游的hander
* handler也可以设置专用线程池去处理
.childHandler(new ChannelInitializer() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(new EchoServerHandler());
p.addLast(new EventExecutorGroup(),new EchoServerHandler()); // 可以为某个handler设置线程池
}
});
{{:pasted:20210730-092825.png}}