客户端的读事件注册是紧接着【4.2.Netty源码:NioSocketChannel的线程分配和selector注册】后面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//AbstractChanne.java
private void register0(ChannelPromise promise) {
try {
...
//调用jdk底层 接口是否绑定了。当服务端启动的时候,isActive()返回false
if (isActive()) {
if (firstRegistration) {
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {
beginRead();
}
}
} catch (Throwable t) {
// Close the channel directly to avoid FD leak.
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
-
【8】扩展说明,如下
1 2 3 4 5
public void channelActive(ChannelHandlerContext ctx) throws Exception { //向下传播事件了 ctx.fireChannelActive(); readIfIsAutoRead(); }
-
【4】继续深入会发现是从tail节点往前传播,再到客户端连接(
NioSocketChannel
)的unsafe.beginRead()
,最终实现方法是在AbstractNioChannel#doBeginRead
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//AbstractNioChannel.java protected void doBeginRead() throws Exception { final SelectionKey selectionKey = this.selectionKey; if (!selectionKey.isValid()) { return; } readPending = true; final int interestOps = selectionKey.interestOps(); if ((interestOps & readInterestOp) == 0) { selectionKey.interestOps(interestOps | readInterestOp); } }
将读事件绑定到selector上。下次如果有数据进来就可以进行数据读写了。此时的
interestOps
是读事件。再构造NioSocketChannel的时候默认定义的.1 2 3
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) { super(parent, ch, SelectionKey.OP_READ); }
-