Table of Contents
1. 相关流程
下面的相关流程特指NioServerSocketChannel/NioSocketChannel
1.1. bind流程
- 新建一个Channel
- 注册到boss group,注册时触发事件
- fireChannelRegistered
- fireChannelActive(如果是第一次注册,例如unregister后再register没有这个事件)
- 调用Java NIO bind到端口
如下图:
- Channel为NioServerChannel或相关子类中的实现
- EventLoopGroup为NioEventLoopGroup或相关子类中的实现
- EventLoop为NioEventLoop或相关子类中的实现
1.2. accept流程
ServerBootstrap继承自AbstractBootStrap,前者在构造时需要两个EventLoopGroup:boss和worker 而后者在构造时,只需要一个EventLoopGroup。这是因为ServerBootstrap把需要bind和listen的Channel让父类处理,处理的逻辑定义在ServerBootstrapAcceptor:
- 实现ChannelInboundHandlerAdapter
- 当channelRead时(有新的Channel时),将childHander应用到该Channel上
- 在worker group上注册这个新的Channel
1.3. connect流程
- 新建一个Channel
- 注册到boss group,注册时触发事件
- fireChannelRegistered
- fireChannelActive(如果是第一次注册,例如unregister后再register没有这个事件)
- resolve name
- 调用channel.connect
1.4. write流程
- 用户调用Channel.write
- 调用Pipeline.tail(TailContext)的write,默认实现是查找下一个个Outbound Context,并根据是否在eventloop,同步或异步的调用ChannelOutboundHandler.write函数
- 我们定义一个ChannelOutboundHandler时,默认在最后也会调用context.write,因此又继续调用下一层
- 最终,会调用到Pipeline.head(HeadContext)的write,默认实现时调用AbstractChannel中的write。
- AbstractChannel的write默认是放到一个ChannelOutboundBuffer,只有flush时才真正write(细节由channel实现)
1.5. read流程
- 读的发起地是NioEventLoop,在处理SelectionKey.OP_READ时发起。首先调用Channel的read(不同channel不同的实现)
- channel的read中,一般读取网络数据后,调用Pipeline.fireChannelRead
- 如上所述,Pipeline.fireChannelRead从head开始,向上查找Inbound Channel Handler,然后调用其invokeChannelRead
- invokeChannelRead会根据是否在event loop中,同步或异步的调用channelRead函数,也就是我们一般会去override函数

0 评论:
Post a Comment