为便于后续阐述,写贴一段分析过程中要用到的源码
public static void main( String[] args )
{
EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new SimpleHandler1());
ch.pipeline().addLast(new SimpleHandler2());
ch.pipeline().addLast(new SimpleHandler3());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture ch = bootstrap.bind(14167).sync();
ch.channel().closeFuture().sync();
} catch (Exception e){
}
finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
public class SimpleHandler1 extends ChannelDuplexHandler {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("---- write 1 ----");
// super.write(ctx, msg, promise);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("---- read 1 ----");
// super.channelRead(ctx, msg);
}
public class SimpleHandler2 extends ChannelDuplexHandler {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
System.out.println("---- write 2 ----");
// super.write(ctx, msg, promise);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("---- read 2 ----");
super.channelRead(ctx, msg);
}
}
public class SimpleHandler3 extends ChannelDuplexHandler {
@Override
public void channelRead(ChannelHandlerContext ctx, final Object msg) throws Exception {
// ctx.channel().writeAndFlush("hi").addListener(ChannelFutureListener.CLOSE);
ctx.writeAndFlush("hi");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("----- INACTIVE -----");
super.channelInactive(ctx);
}
@Override
public void close(ChannelHandlerContext ctx, ChannelPromise future) throws Exception {
System.out.println("----- CLOSE -----");
super.close(ctx, future);
}
}
结合前文的分析,当有新的客户端连接上来后,将会给客户端分配一个NioSocketChannel 以及对应的DefaultChannelpipeline, 该pipelie上会有3个ChannelHandlerContext( 不包含head和tail), 此时pipleline 结构示意图如下
从调试中我们也可看出
接下里在看看客户端 发送数据后的处理过程
先说下结论、然后再分析过程
1. 当客户端发送数据后先调用DefaultChannelPipeline 的fireChannelRead()
2. DefaultChannelPipeline 会从head ChannelHandlerContext 开始找,找到一个MASK_CHANNEL_READ类型的ChannelHandlerContext
3. ChannelHandlerContext 最终调用它指向的ChannelHandler的 channelRead()方法
下面是整个过程的时序图
接下来看下上述过程的源码 DefaultChannelPipeline 的fireChannelRead()
找到一个MASK_CHANNEL_READ类型的ChannelHandlerContext
调用它指向的ChannelHandler的 channelRead()方法
最终进入自己写的SimpleHandler1的channelRead() 方法
结论
1. 当客户端发送数据后先调用DefaultChannelPipeline 的fireChannelRead()
2. DefaultChannelPipeline 会从head ChannelHandlerContext 开始找,找到一个MASK_CHANNEL_READ类型的ChannelHandlerContext
3. ChannelHandlerContext 最终调用它指向的ChannelHandler的 channelRead()方法