入口
private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
...
// 服务器收到Accept事件,来到这里准备新连接的处理
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
unsafe.read();
...
}
...
}
接下来开始接入新连接,read会将拿到的新连接存在本地的readBuf中。
public void read() {
assert eventLoop().inEventLoop();
final ChannelConfig config = config();
final ChannelPipeline pipeline = pipeline();
final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
allocHandle.reset(config);
boolean closed = false;
Throwable exception = null;
try {
try {
do {
// doReadMessages拿底层accept的socketchannel
// 将拿到的channel收集到本地readBuf
int localRead = doReadMessages(readBuf);
if (localRead == 0) {
break;
}
if (localRead < 0) {
closed = true;
break;
}
allocHandle.incMessagesRead(localRead);
// 判断是否还可以继续接入新连接
} while (allocHandle.continueReading());
} catch (Throwable t) {
exception = t;
}
int size = readBuf.size();
// 遍历上面收集到的连接channel,逐个触发fireChannelRead
// 而这里触发的pipeline的handler是服务端启动的时候默认加载的ServerBootstrapAcceptor
for (int i = 0; i < size; i ++) {
readPending = false;
pipeline.fireChannelRead(readBuf.get(i));
}
readBuf.clear();
allocHandle.readComplete();
pipeline.fireChannelReadComplete();
...
} finally {
...
}
}
组装SocketChannel
protected int doReadMessages(List
Channel分类
NioSocketChannel结构
创建NioSocketChannel
public NioSocketChannel(Channel parent, SocketChannel socket) {
super(parent, socket);
config = new NioSocketChannelConfig(this, socket.socket());
}
AbstractNioByteChannel
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {
// 将OP_READ往上传,说明新连接建立后,服务器开始接收READ事件
super(parent, ch, SelectionKey.OP_READ);
}
AbstractNioChannel
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
super(parent);
// 保存NIO的SocketChannel
this.ch = ch;
// 保存READ事件码
this.readInterestOp = readInterestOp;
try {
// 设置NIO非阻塞模式
ch.configureBlocking(false);
} catch (IOException e) {
...
}
}
AbstractChannel
protected AbstractChannel(Channel parent) {
// NioServerSocketChannel
this.parent = parent;
id = newId();
unsafe = newUnsafe();
pipeline = newChannelPipeline();
}
config
public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
super(channel);
if (javaSocket == null) {
throw new NullPointerException("javaSocket");
}
this.javaSocket = javaSocket;
// Enable TCP_NODELAY by default if possible.
if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
try {
// 设置TcpNoDelay,不会攒包,有的话立即发送
setTcpNoDelay(true);
} catch (Exception e) {
// Ignore.
}
}
}
ServerBootstrapAcceptor
fireChannelRead
public void channelRead(ChannelHandlerContext ctx, Object msg) {
final Channel child = (Channel) msg;
// childHandler添加到子连接的pipeline中,也就是ChannelInitializer
// 这里作为pipeline的起手式,将该ChannelInitializer作为该pipeline的第一个执行者
child.pipeline().addLast(childHandler);
// 设置options到客户端channel的config
for (Entry, Object> e: childOptions) {
try {
if (!child.config().setOption((ChannelOption
register
public ChannelFuture register(Channel channel) {
// next就是拿到下一个EventLoop,NioEventLoopGroup的chooser来滚动整个EventLoop数组
// 继续往下探
return next().register(channel);
}
public ChannelFuture register(Channel channel) {
// 对channel进行简单封装成Promise
return register(new DefaultChannelPromise(channel, this));
}
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
...
AbstractChannel.this.eventLoop = eventLoop;
// 当前是boss发起,那么这里必然进不去
if (eventLoop.inEventLoop()) {
register0(promise);
} else {
try {
// 这里新建线程运行,并跟eventLoop绑定,之后就由该线程与channel进行互动
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
...
}
}
}
private void register0(ChannelPromise promise) {
try {
boolean firstRegistration = neverRegistered;
doRegister();
neverRegistered = false;
registered = true;
pipeline.invokeHandlerAddedIfNeeded();
safeSetSuccess(promise);
pipeline.fireChannelRegistered();
if (isActive()) {
if (firstRegistration) {
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {
...
beginRead();
}
}
} catch (Throwable t) {
...
}
}
doRegister
protected void doRegister() throws Exception {
boolean selected = false;
for (;;) {
try {
// 终于看到NIO的调用,将selector与channel绑定
// 至此底层注册完成
selectionKey = javaChannel().register(eventLoop().selector, 0, this);
return;
} catch (CancelledKeyException e) {
...
}
}
}
invokeHandlerAddedIfNeeded
final void invokeHandlerAddedIfNeeded() {
assert channel.eventLoop().inEventLoop();
if (firstRegistration) {
firstRegistration = false;
// 接着去调用callHandlerAddedForAllHandlers
callHandlerAddedForAllHandlers();
}
}
private void callHandlerAddedForAllHandlers() {
final PendingHandlerCallback pendingHandlerCallbackHead;
synchronized (this) {
assert !registered;
// This Channel itself was registered.
registered = true;
pendingHandlerCallbackHead = this.pendingHandlerCallbackHead;
// Null out so it can be GC'ed.
this.pendingHandlerCallbackHead = null;
}
// 那么这个pendingHandlerCallbackHead到底是哪里来的,要记得上面boss在fireChannelRead的时候会
// addLast一个ChannelInitializer么?
PendingHandlerCallback task = pendingHandlerCallbackHead;
while (task != null) {
// 那么这里的execute
task.execute();
task = task.next;
}
}
ChannelInitializer
addLast
public final ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) {
...
// 将ChannelInitializer保证成nexCtx
newCtx = newContext(group, filterName(name, handler), handler);
...
// 如果是客户端channel还没有注册到这个EventLoop上,调用callHandlerCallbackLater,将 // ChannelInitializer与pendingHandlerCallbackHead进行绑定
// 实际上这个handler将作为客户端pipeline的head来处理,且初始化完成后会remove掉自己
if (!registered) {
newCtx.setAddPending();
callHandlerCallbackLater(newCtx, true);
return this;
}
...
}
execute
void execute() {
EventExecutor executor = ctx.executor();
if (executor.inEventLoop()) {
// 最终会调用callHandlerAdded0
callHandlerAdded0(ctx);
} else {
try {
executor.execute(this);
} catch (RejectedExecutionException e) {
...
}
}
}
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
if (ctx.channel().isRegistered()) {
// 会最终会执行Initializer的initChannel
initChannel(ctx);
}
}
private boolean initChannel(ChannelHandlerContext ctx) throws Exception {
if (initMap.putIfAbsent(ctx, Boolean.TRUE) == null) { // Guard against re-entrance.
try {
// 这里真正开始执行用户自定义的Initializer的initChannel方法
initChannel((C) ctx.channel());
} catch (Throwable cause) {
...
} finally {
// 责任链初始化完成后会移除该Initializer,这样整个客户端pipeline的责任链初始化完成
remove(ctx);
}
return true;
}
return false;
}
fireChannelRegistered
public ChannelHandlerContext fireChannelRegistered() {
// 遍历pipeline的handler执行invokeChannelRegistered
invokeChannelRegistered(findContextInbound());
return this;
}
private AbstractChannelHandlerContext findContextInbound() {
AbstractChannelHandlerContext ctx = this;
do {
// 拿到下一个handler
ctx = ctx.next;
} while (!ctx.inbound);
return ctx;
}
private void invokeChannelRegistered() {
if (invokeHandler()) {
try {
// 执行channelRegistered方法
((ChannelInboundHandler) handler()).channelRegistered(this);
} catch (Throwable t) {
notifyHandlerException(t);
}
} else {
fireChannelRegistered();
}
}
fireChannelActive
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 将ChannelActive事件在pipeline上继续往后传播,也就是执行各个链上的channelActive方法
ctx.fireChannelActive();
// 开始正式read
readIfIsAutoRead();
}
read
private void readIfIsAutoRead() {
if (channel.config().isAutoRead()) {
// 这里会在底层注册给selector注册通道的read事件
channel.read();
}
}
protected void doBeginRead() throws Exception {
// Channel.read() or ChannelHandlerContext.read() was called
final SelectionKey selectionKey = this.selectionKey;
if (!selectionKey.isValid()) {
return;
}
readPending = true;
final int interestOps = selectionKey.interestOps();
if ((interestOps & readInterestOp) == 0) {
// 前面register的时候,没有注册任何事件,也就是0,这里开始注册read,说明前期准备工作已经完成
// 可以正式开始接收客户端发来的数据了
// 而这里的readInterestOp是创建NioSocketChannel的时候指定的OP_READ事件
// NIO的代码,做ready注册
selectionKey.interestOps(interestOps | readInterestOp);
}
}