Netty的inBound事件的处理过程分析

为便于后续阐述,写贴一段分析过程中要用到的源码

    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()方法

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值