client启动:
server是在bootstrap.bind的时候启动,而同样,client是在bootstrap.connect时启动,流程都是一样的:创建NioSocketChannel,和workgroup中的一个eventloop绑定起来,然后再执行connect。
笔记:connect操作和write操作一样,都是客户端主动调用,然后write事件被丢到netty,而网络可读可写等事件则是由netty自动接收然后处不处理后再丢到pipeline,然后pipeline中的handler再调用我们的程序,也就是说前者是由netty外到netty内,后者是由netty内到netty外。
建议copy到本地阅读
BootStrap.connectBootStrap.doResolveAndConnectAbstractBootStrap.initAndRegister #创建NioSocketChannel并且注册到workgoup的某个eventloop线程对应的selector中,然后发送channelRegister事件,略BootStrap.doResolveAndConnect0 #执行连接操作BootStrap.doConnectAbstractChannel.connect #这里就开始和NioServerSocketChannel的bind一样了,一路connect,最终来到java nio socket的connect#然后connect成功后再发送channelActive事件DefaultChannelPipeline.connectAbstractChannelHandlerContext.connect #tail.connectAbstractChannelHandlerContext.connect #重载AbstractChannelHandlerContext.invokeConnect #调用handler的connect函数MyHandler.connect #我们自定义的handler......HeadContext.connect #最终来到了headContext的connect,由此可见网络数据的进出都由headcontext负责#正因为数据进出都要通过connect,所以connect的时候从tail开始往前就可以理解了AbstractNioUnsafe.connect #boolean connected = SocketUtils.connect #调用java Nio 的connect,所以netty就是对java nio的一个封装if (!connected) {selectionKey().interestOps(SelectionKey.OP_CONNECT); #丢到eventloop,因为connect不一定立即成功}......略......NioEventLoop.processSelectedKey #上一步我们向selector注册了OP_CONNECT事件,然后就进入eventloop循环了,#当connect成功以后就会唤醒selector,然后走select流程#直接来到这里processSelectedKey,前面的代码略if ((readyOps & SelectionKey.OP_CONNECT) != 0):k.interestOps #从selector中取消监听connect事件,因为channel连接只需要一次AbstractNioUnsafe.finishConnect AbstractNioUnsafe.fulfillConnectPromiseDeafultChannelPipeline.fireChannelActive #连接成功以后把channelActive事件丢到pipeline,#然后后面就是pipeline的流程,即依次调用handler的channelActive方法,后续流程略