服务端启动流程
// ServerSocketChannel初始化注册过程
bind(int inetPort)
- doBind(final SocketAddress localAddress)
- initAndRegister()
- this.channelFactory.newChannel()(实例化NioServerSocketChannel,执行NioServerSocketChannel构造方法,super((Channel)null, channel, OP_ACCEPT))
- ServerBootstrap.init(channel): 为通道设置options和attrs,pipeline添加ChannelInitializer(handler()方法配置的处理器和ServerBootstrap.ServerBootstrapAcceptor)
- this.config().group().register(channel)(此处group为bossGroup)
- MultithreadEventLoopGroup.register
- SingleThreadEventLoop.register
- AbstractChannel.register
- AbstractUnsafe.this.register0(promise)
- this.pipeline.invokeHandlerAddedIfNeeded(): 执行ChannelInitializer.initChannel,为serverSocketChannel pipeline添加处理器
-触发inbound事件fireChannelRegistered,已激活(首次注册触发fireChannelActive,否则为通道添加selectionKey.interestOps事件)
注意点:selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this) ,为什么注册interestOps=0?
由于NioServerSocketChannel初始化过程中,为其属性interestOps设置为OP_ACCEPT,而注册时初始化SelectionKey的interestOps为0,最终决定注册事件在AbstractNioChannel.doBeginRead上,将通道初始化时的interestOps与SelectionKey的interestOps做&与操作,为0说明事件不重合。最终得到selectionKey.interestOps(interestOps | this.readInterestOp)。
服务端接收客户端连接请求过程
// 接收socket连接
NioEventLoop.run()
- processSelectedKeys()
- processSelectedKeysOptimized()
- processSelectedKey(SelectionKey k, AbstractNioChannel ch)
- unsafe.read()
- NioMessageUnsafe.read
- doReadMessages (SocketUtils.accept 生成NioSocketChannel)
- inbound事件流向(head ... tail)pipeline.fireChannelRead(this.readBuf.get(i))(执行各个inboundHandler的channelRead,其中ServerBootstrapAcceptor.channelRead,主要做了为该socketchannel pipeline添加childHandler)
- 通道注册childGroup.register(child)(此处group为workGroup)
- MultithreadEventLoopGroup.register
- SingleThreadEventLoop.register
- AbstractChannel.register
- AbstractUnsafe.this.register0(ChannelPromise promise)
- AbstractChannel.this.pipeline.invokeHandlerAddedIfNeeded() (该方法中触发了ChannelInitializer.initChannel)
- AbstractChannel.this.pipeline.fireChannelRegistered()(触发fireChannelRegistered inbound事件)
- 如果通道已激活(首次注册触发fireChannelActive事件,否则为通道添加OP_READ事件)
客户端启动流程
bootstrap.connect(HOST, PORT)
- doResolveAndConnect(remoteAddress, localAddress)
- doResolveAndConnect0(channel, remoteAddress, localAddress, channel.newPromise())(前提注册成功)
- doConnect(remoteAddress, localAddress, promise)
- AbstractChannel.connect(remoteAddress, promise)
- this.pipeline.connect(remoteAddress, promise) (DefaultChannelPipeline)
- this.tail.connect(remoteAddress, promise) (DefaultChannelPipeline) 触发outBound事件,事件流向从tail...head.
- AbstractChannelHandlerContext.connect(remoteAddress, promise)
- AbstractChannelHandlerContext.connect(remoteAddress, localAddress, promise)
- next.invokeConnect(remoteAddress, localAddress, promise)(遍历outBoundHandler)
- ((ChannelOutboundHandler)this.handler()).connect(this, remoteAddress, localAddress, promise)(从tail开始往前查找outbound为true的handler,执行connect,
headContext实现了OutBoundHandler,最终会调用到headContext.connect())
- this.unsafe.connect(remoteAddress, localAddress, promise)(this指DefaultChannelPipeline)
- AbstractNioChannel.connect(remoteAddress, localAddress, promise)
- AbstractNioChannel.this.doConnect(remoteAddress, localAddress)
- NioSocketChannel.doConnect(remoteAddress, localAddress)
- SocketUtils.connect(this.javaChannel(), remoteAddress)(未连接,设置OP_CONNECT连接事件)
- jdk os底层连接过程