netty4handler的执行顺序一

最近在学netty4,原因是netty5被netty放弃了,不过在学习过程中,由于半吊子,对handler的执行顺序有很不明白,看了网上的资料也不明白,虽然说了in的情况是按照进入pipeline的顺序执行,而out是逆序执行,但是写起来,运行起来还是有异常,这个是写做出来的问题,今天记录下过程,首先声明本章不应该作为开发的使用,因为,本身是错误的(不能说错误,但是不对),只是服务端,客户端,随便用一个即可

public class WangNetty4Server {

    private static final Logger LOGGER = LoggerFactory.getLogger(WangNetty4Server.class);
    
    public void start(int port){
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        try {
            bootstrap.group(boss, work)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 1024)
//            .option(ChannelOption.SO_TIMEOUT, 5 * 1000)
            .childOption(ChannelOption.SO_KEEPALIVE, true)
            .childOption(ChannelOption.SO_RCVBUF, 10 * 1024)
            .childOption(ChannelOption.SO_SNDBUF, 10 * 1024)
            .childHandler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel sc) throws Exception {
                    sc.pipeline().addLast(new WangInHandler1());
                    sc.pipeline().addLast(new WangInHandler2());
//                    sc.pipeline().addLast(new WangInHandler3());
                }
            });
            ChannelFuture future = bootstrap.bind(port).sync();
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            LOGGER.error("server 启动失败",e);
        }finally{
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
    
    public static void main(String[] args) {
        WangNetty4Server server = new WangNetty4Server();
        server.start(8085);
    }

}



public class WangInHandler1 extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // TODO Auto-generated method stub
//        super.channelRead(ctx, msg);
        System.out.println(" WangInHandler1  channelRead");
        ctx.fireChannelRead(msg);
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelReadComplete(ctx);
        System.out.println(" WangInHandler1  channelReadComplete");
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(ctx, cause);
        System.out.println(" WangInHandler1  exceptionCaught");
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelActive(ctx);
        System.out.println(" WangInHandler1  channelActive");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelInactive(ctx);
        System.out.println(" WangInHandler1  channelInactive");
    }
    
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelRegistered(ctx);
        System.out.println(" WangInHandler1  channelRegistered");
    }
    
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelUnregistered(ctx);
        System.out.println(" WangInHandler1  channelUnregistered");
    }
    
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx)
            throws Exception {
        // TODO Auto-generated method stub
        super.channelWritabilityChanged(ctx);
        System.out.println(" WangInHandler1  channelWritabilityChanged");
    }
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // TODO Auto-generated method stub
        super.userEventTriggered(ctx, evt);
        System.out.println(" WangInHandler1  userEventTriggered");
    }

}



public class WangInHandler2 extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // TODO Auto-generated method stub
//        super.channelRead(ctx, msg);
        System.out.println(" WangInHandler2  channelRead");
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelReadComplete(ctx);
        System.out.println(" WangInHandler2  channelReadComplete");
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(ctx, cause);
        System.out.println(" WangInHandler2  exceptionCaught");
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelActive(ctx);
        System.out.println(" WangInHandler2  channelActive");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelInactive(ctx);
        System.out.println(" WangInHandler2  channelInactive");
    }
    
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelRegistered(ctx);
        System.out.println(" WangInHandler2  channelRegistered");
    }
    
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelUnregistered(ctx);
        System.out.println(" WangInHandler2  channelUnregistered");
    }
    
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx)
            throws Exception {
        // TODO Auto-generated method stub
        super.channelWritabilityChanged(ctx);
        System.out.println(" WangInHandler2  channelWritabilityChanged");
    }
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // TODO Auto-generated method stub
        super.userEventTriggered(ctx, evt);
        System.out.println(" WangInHandler2  userEventTriggered");
    }

}



public class WangInHandler3 extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // TODO Auto-generated method stub
//        super.channelRead(ctx, msg);
        System.out.println(" WangInHandler3  channelRead");
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelReadComplete(ctx);
        System.out.println(" WangInHandler3  channelReadComplete");
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        super.exceptionCaught(ctx, cause);
        System.out.println(" WangInHandler3  exceptionCaught");
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelActive(ctx);
        System.out.println(" WangInHandler3  channelActive");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelInactive(ctx);
        System.out.println(" WangInHandler3  channelInactive");
    }
    
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelRegistered(ctx);
        System.out.println(" WangInHandler3  channelRegistered");
    }
    
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        super.channelUnregistered(ctx);
        System.out.println(" WangInHandler3  channelUnregistered");
    }
    
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx)
            throws Exception {
        // TODO Auto-generated method stub
        super.channelWritabilityChanged(ctx);
        System.out.println(" WangInHandler3  channelWritabilityChanged");
    }
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // TODO Auto-generated method stub
        super.userEventTriggered(ctx, evt);
        System.out.println(" WangInHandler3  userEventTriggered");
    }

}

大家看到了,我实现的是ChannelInboundHandlerAdapter方法,每个方法中先super(),然后打印System.out

先说明1)channelRead()方法需要使用ctx.fireChannelRead(msg);才会向下一个inhandler,传递,也就是super.channelRead(ctx, msg);,其实super的这个方法,就是ctx.fireChannelRead(msg);

执行结果

 WangInHandler2  channelRegistered
 WangInHandler1  channelRegistered
 WangInHandler2  channelActive
 WangInHandler1  channelActive
 WangInHandler1  channelRead
 WangInHandler2  channelRead
 WangInHandler2  channelReadComplete

 WangInHandler1  channelReadComplete

下面是客户端主动停止报的异常

 WangInHandler2  channelReadComplete[nioEventLoopGroup-3-1] WARN io.netty.channel.DefaultChannelPipeline - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
 WangInHandler1  channelReadComplete

java.io.IOException: Connection reset by peer
    at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
    at sun.nio.ch.IOUtil.read(IOUtil.java:192)
    at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:379)
    at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:288)
    at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1108)
    at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:345)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:148)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.lang.Thread.run(Thread.java:745)
 WangInHandler2  exceptionCaught
 WangInHandler1  exceptionCaught
 WangInHandler2  channelInactive
 WangInHandler1  channelInactive
 WangInHandler2  channelUnregistered
 WangInHandler1  channelUnregistered


大家从日志中看到,似乎与网上说的先进先出,不一致,只有channelread()是一致的,我当时也是这样认为的,其实这个是错误的,原因是我的写作方法问题,应该是先执行我们自己的方法,然后在super方法,之所以channelread显示对,因为

        System.out.println(" WangInHandler1  channelRead");

        ctx.fireChannelRead(msg);我先打印后执行了super方法

本例子不对,看下一例子








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值