Netty启动流程

服务端启动流程

// 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底层连接过程

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值