netty4handler的执行顺序二

接上一篇,上一篇是不对的处理方式,看本篇,我认为是对的


/**
 * 这个用于测试handler的传递功能
 * @author wangzg
 *
 * 本例子使用的是 实现的handler中,各个函数都是先super,然后打印,除了handler1中的channelRead,这样打印出的顺序是,先2后1,也就是最后加进去的,先做,先进去的后做,跟
 * 网上的不一致
 *
 * 本例子中各个handler中的方法,都在最后使用了super()的方法,顺序和网上的一致
 *
 */
public class WangNetty44Server {

    private static final Logger LOGGER = LoggerFactory.getLogger(WangNetty44Server.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) {
        WangNetty44Server server = new WangNetty44Server();
        server.start(8085);
    }

}



import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class WangInHandler1 extends ChannelInboundHandlerAdapter {

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

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

}



public class WangInHandler2 extends ChannelInboundHandlerAdapter {

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

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


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
        System.out.println(" WangInHandler3  channelReadComplete");
        super.channelReadComplete(ctx);
        
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  exceptionCaught");
        super.exceptionCaught(ctx, cause);
        
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelActive");
        super.channelActive(ctx);
        
    }

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


执行结果

 WangInHandler1  channelRegistered
 WangInHandler2  channelRegistered
 WangInHandler3  channelRegistered
 WangInHandler1  channelActive
 WangInHandler2  channelActive
 WangInHandler3  channelActive
 WangInHandler1  channelRead
 WangInHandler2  channelRead
 WangInHandler3  channelRead

 WangInHandler1  channelReadComplete
 WangInHandler2  channelReadComplete

 WangInHandler3  channelReadComplete

下面是客户端主动停止通讯

 WangInHandler1  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.
 WangInHandler2  channelReadComplete
 WangInHandler3  channelReadComplete
 WangInHandler1  exceptionCaught
 WangInHandler2  exceptionCaught
 WangInHandler3  exceptionCaught

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)
 WangInHandler1  channelInactive
 WangInHandler2  channelInactive
 WangInHandler3  channelInactive
 WangInHandler1  channelUnregistered
 WangInHandler2  channelUnregistered
 WangInHandler3  channelUnregistered

大家看到我把System.out和super()调换了,就执行顺序对了,都是1,2,3的执行顺序,因此每次都应该先执行自己的业务,然后super()

需要注意的是每次向下一handler发送的时候,都需要super.channelRead(ctx, msg);它,如果handler2把他注释掉,handler3就无法channelread了,执行结果


 WangInHandler1  channelRegistered
 WangInHandler2  channelRegistered
 WangInHandler3  channelRegistered
 WangInHandler1  channelActive
 WangInHandler2  channelActive
 WangInHandler3  channelActive
 WangInHandler1  channelRead
 WangInHandler2  channelRead

 WangInHandler1  channelReadComplete
 WangInHandler2  channelReadComplete
 WangInHandler3  channelReadComplete
 WangInHandler1  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.
 WangInHandler2  channelReadComplete
 WangInHandler3  channelReadComplete
 WangInHandler1  exceptionCaught
 WangInHandler2  exceptionCaught
 WangInHandler3  exceptionCaught

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)
 WangInHandler1  channelInactive
 WangInHandler2  channelInactive
 WangInHandler3  channelInactive
 WangInHandler1  channelUnregistered
 WangInHandler2  channelUnregistered

 WangInHandler3  channelUnregistered

大家可以看到标红的区别

本篇个人认为是对的,下一篇描述不使用super的问题


猜你喜欢

转载自blog.csdn.net/fivestar2009/article/details/80493611