前情提要
在Netty学习笔记之服务端启动一文中,我们了解了eventloop
的基本功能,知道了它的一生其实就是个死循环,再循环里处理IO
事件和taskQueue
里面的任务;同时我们也了解到,在服务端启动之初(准确的来讲是在channel
注册完成之后调用handlerAdded
的时候)会给pipeline
里添加一个特殊的handler
:ServerBootstrapAcceptor,有了这两点之后,让我们看下Netty
服务端启动后是如何利用reactor
模型建立新连接的。
正文
当客户端启动并给服务端发送消息后,服务端的eventloop
就会监听到对应事件:
NioEventLoop.run
1 | protected void run() { |
NioEventLoop.processSelectedKey
1 | private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) { |
NioMessageUnsafe.read
1 | public void read() { |
最终调用了pipeline.fireChannelRead(readBuf.get(i))
, 在服务端启动一文中我们也讲到了pipeline
的传播,像这种firexxx
的都是从head
往后传播的,所以最终会传播到ServerBootstrapAcceptor
里,调用ServerBootstrapAcceptor
的channelRead
,而这里,就是重头戏了。
ServerBootstrapAcceptor.channelRead

这里有几个点需要注意下:
代码①:这里的
Channel
是SockerChannel
,而不是ServerSocketChannel
,即是客户端的Channel
.代码②:
childHandler
就是我们在boostrap
里配的ChannelInitializer
,等到channel
真正注册后回调initChannel
方法,把MyServerHandler
添加到pipeline
,见下图,这里的处理和服务端启动一文中doResigter
一节中的代码②是一个道理,归根到底就是因为我们想给pipeline
添加handler
,但是Channel
还没注册好,所以采取的一种妥协的方式,即先给pipeline
注册一个ChannelInitializer
类型的Handler
,等到Channel
真正注册好之后,再去回调这个特殊Handler
的initChannel
方法。这里也可以解释
bootstrap
的handler
和childHanlder
的区别:前者对应ServerSocketChannel
,后者对应SockerChannel
.
代码③:这里就是将
channel
注册到eventloop
上,和我们在服务端启动一文中看到的serversocketChannel
的注册差不多,但是有细微区别,主要体现在服务端启动时的注册是将
serversocketChannel
注册到bossGroup
里的eventloop
.而childChannel
注册时是要注册到workerGroup
里。在注册环节,由于当前线程是
bossGroup
的线程,所以一定会走else
的逻辑, 将注册的任务提交到childChannel
自己的eventloop