netty启动流程
2022-03-21 15:52:04 0 举报
netty启动流程
作者其他创作
大纲/内容
HeadContext#channelRead()
否
takeTask
一、服务器启动流程
eventloop为bossGroup中的线程
AbstractChannel#doBeginRead()
SingleThreadEventExecutor#addTask(taskl)
processSelectedKey()
select()
HeadContext#readIfIsAutoRead()
NioSocketChanne#register0()
workGroup中的线程
AbstractChannel#bind0
执行初始化器中的nitChannel方法
直接执行register0
AbstractChannel.register(eventLoop)
1.设置channel连接的options及attr。2.添加ChannelInitializer初始化器,用于增加ServerBootstrapAcceptor handler,将workerGroup线程组、childHandler传入及options及attrs传入,用于bossGroup与workerGroup的切换
1.1 添加regist0()任务
cilent connected
是
2.1 addTask(doBind0)
1.初始化options及attrs.2.使用childGroup(workGroup)处理消息,即封装的NioSocketChanne对象3.childGroup.register(child)执行注册
当前线程释放为eventLoop线程
三、服务端接受消息流程
invokeHandlerAddedIfNeeded放到调用后,会执行init方法中加入的初始化器(ChannelInitializer)的initChannel方法,将ServerBootstrapAcceptor加入到NioServerSocketChannel中的pipline中。此方法调用后会执行HandlerAdded中的handlerAdded()方法,handlerAdded()方法中会调用initChannel(ctx)方法
SingleThreadEventExecutor.this.run()
NioEventLoop#processSelectedKeysOptimized
client write message
eventLoop.execute(task)
AbstractChannel#doRegister()
taskQueue
AbstractNioChannel#doBeginRead()
runTask()
1.开启新的线程(workGroup中的线程)。2.在新线程中执行SingleThreadEventExecutor.this.run()。一直一直循环监听是否有新的任务或者新的IO事件3.由于之前已经加入了register0()的任务,因此select返回结果,执行后注册任务
AbstractBootstrap.doBind0addTask(doBind())
1.2 执行register0()任务
eventLoop.execute(register0())
mian线程
AbstractBootstrap.initAndRegister()
AbstractNioChannel#pipeline.fireChannelActive()
AbstractChannel#register0()
注册感兴趣事件:SelectionKey.OP_ACCEPT,相当于Nio中: selectionKey.interestOps(SelectionKey.OP_ACCEPT);
1.通过doReadMessages()方法初始化接受的数据2.执行pipeline.fireChannelRead(byteBuf)方法,将消息传递到handler。3.此时消息由pipline中的HeadContex接收数据。
二、客户端连接流程
selectedKey OP_ACCEPT
1.2执行register0()任务
HeadContext#channelActive()
执行原生的nio注册serverSocketChannel.bind(new InetSocketAddress(8080));
AbstractNioChannel#addtask(pipeline.fireChannelActive())
1.通过doReadMessages()方法初始化SocketChannel原生对象,并封装为NioServerSocket对象,并将NioServerSocket处理为传递的消息2.执行 pipeline.fireChannelRead(readBuf.get(i));方法,NioServerSocket对象当做消息往下传递。3.此时pipline中的handler顺序为:head->accept->tail。接下来由acceptHandler处理消息。
AbstractBootstrap.dobind()
原生的 nio channel 绑定到 selector 上,注意此时没有注册 selector 关注事件
NioServerSocketChannel#doBind0
根据key的类型区分IO事件进行执行unsafe.read();
ServerBootstrap.bind(8080)
AbstractNioMessageChannel.NioByteUnsafe#read()
selectedKey OP_READ
SingleThreadEventExecutor#startThread
3.2 执行pipeline.fireChannelActive()任务
1.通过ReflectiveChannelFactory反射申生成NioServerSocketChannel对象。2.NioServerSocketChannel设置为非堵塞模式。3.初始化channelPipline对象。4.初始化NioServerSocketChannelConfig对象。
DefaultChannelPipeline#readIfIsAutoRead()
注册感兴趣事件:SelectionKey.OP_READ,相当于Nio中: selectionKey.interestOps(SelectionKey.OP_READ);
EventLoop
3.1 addTask(pipeline.fireChannelActive())
NioSocketChanne#register()
headContext中执行channelRead()方法后执行 ctx.fireChannelRead(msg),将msg传递个下一个handler。
ServerBootstrapAcceptor#channelRead()
doRegister()执行原生socketChannel的注册,将socketChannel注册的selector上
1.1 addTask(register0())
bossGroup中的线程
pipeline.fireChannelActive();触发HeadContext中的channelActive()方法
2.2 执行doBind0()任务
pipeline.invokeHandlerAddedIfNeeded()执行用户自定义的childHandler中的initChannel()方法,将各种解码器及自定义的handler加入到channel的pipline中。
pipeline.invokeHandlerAddedIfNeeded();
ServerBootstrap.init(channel)
AbstractNioMessageChannel.NioMessageUnsafe#read()
SocketChannel socketChannel = ServerSocketChannel.accept();
AbstractBootstrap.init(channel)
0 条评论
下一页