• netty使用(6)handler 执行顺序问题


    Netty中,可以注册多个handler。ChannelInboundHandler按照注册的先后顺序执行;ChannelOutboundHandler按照注册的先后顺序逆序执行,

    1、ChannelInboundHandler之间的传递,通过调用 ctx.fireChannelRead(msg) 实现;调用ctx.write(msg) 将传递到ChannelOutboundHandler。

    2、ctx.write()方法执行后,需要调用flush()方法才能令它立即执行。

    3、ChannelOutboundHandler 在注册的时候需要放在最后一个ChannelInboundHandler之前,否则将无法传递到ChannelOutboundHandler。

    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.channel.ChannelInitializer;  
    import io.netty.channel.ChannelOption;
    import io.netty.channel.ChannelOutboundHandlerAdapter;
    import io.netty.channel.ChannelPromise;
    import io.netty.channel.EventLoopGroup;  
    import io.netty.channel.nio.NioEventLoopGroup;  
    import io.netty.channel.socket.SocketChannel;  
    import io.netty.channel.socket.nio.NioServerSocketChannel;  
    
    public class HelloServer {  
        public void start(int port) throws Exception {  
            EventLoopGroup bossGroup = new NioEventLoopGroup();   
            EventLoopGroup workerGroup = new NioEventLoopGroup();  
            try {  
                ServerBootstrap b = new ServerBootstrap();   
                b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)   
                        .childHandler(new ChannelInitializer<SocketChannel>() {   
                                    @Override  
                                    public void initChannel(SocketChannel ch) throws Exception {  
                                        // 注册两个OutboundHandler,执行顺序为注册顺序的逆序,所以应该是OutboundHandler2 OutboundHandler1  
                                        ch.pipeline().addLast(new OutboundHandler1());  
                                        ch.pipeline().addLast(new OutboundHandler2());  
                                        // 注册两个InboundHandler,执行顺序为注册顺序,所以应该是InboundHandler1 InboundHandler2  
                                        ch.pipeline().addLast(new InboundHandler1());  
                                        ch.pipeline().addLast(new InboundHandler2());  
                                    }  
                                }).option(ChannelOption.SO_BACKLOG, 128)   
                        .childOption(ChannelOption.SO_KEEPALIVE, true);   
      
                ChannelFuture f = b.bind(port).sync();   
      
                f.channel().closeFuture().sync();  
            } finally {  
                workerGroup.shutdownGracefully();  
                bossGroup.shutdownGracefully();  
            }  
        }  
        public static void main(String[] args) throws Exception {  
            HelloServer server = new HelloServer();  
            server.start(8000);  
        }  
    }
    class InboundHandler1 extends ChannelInboundHandlerAdapter {  
        @Override  
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
            System.out.println("inboundHandler 1 read");
            // 通知执行下一个InboundHandler
            ctx.fireChannelRead(msg);  
        }  
        @Override  
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
            System.out.println("inboundHandler 1 read complete");
            ctx.flush();  
        }  
    }  
    class InboundHandler2 extends ChannelInboundHandlerAdapter {  
        @Override  
        // 读取Client发送的信息,并打印出来  
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
            System.out.println("inboundHandler 2 read");
            ByteBuf result = (ByteBuf) msg;  
            byte[] result1 = new byte[result.readableBytes()];  
            result.readBytes(result1);  
            String resultStr = new String(result1);  
            System.out.println("Client said:" + resultStr);  
            result.release();  
      
            ctx.write(msg);  
        }  
      
        @Override  
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
            //logger.info("InboundHandler2.channelReadComplete");
            System.out.println("inboundHandler 2 read complete");
            ctx.flush();  
        }  
      
    }  
    class OutboundHandler1 extends ChannelOutboundHandlerAdapter {  
        @Override  
        // 向client发送消息  
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {  
           // logger.info("OutboundHandler1.write");
            System.out.println("outboundHandler 1 write");
            String response = "I am ok!";  
            ByteBuf encoded = ctx.alloc().buffer(4 * response.length());  
            encoded.writeBytes(response.getBytes());  
            ctx.write(encoded);  
            ctx.flush();  
        }  
          
          
    }  
    class OutboundHandler2 extends ChannelOutboundHandlerAdapter {  
        @Override  
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {  
            //logger.info("OutboundHandler2.write");  
            // 执行下一个OutboundHandler 
            System.out.println("outboundHandler 2 write");
            super.write(ctx, msg, promise);  
        }  
    }  

    输出为

    inboundHandler 1 read
    inboundHandler 2 read
    Client said:are you alright?
    outboundHandler 2 write
    outboundHandler 1 write
    inboundHandler 1 read complete
  • 相关阅读:
    Lucene学习总结之七:Lucene搜索过程解析
    Lucene学习总结之六:Lucene打分公式的数学推导
    Lucene学习总结之五:Lucene段合并(merge)过程分析
    Lucene学习总结之四:Lucene索引过程分析
    Lucene学习总结之三:Lucene的索引文件格式(1)
    Lucene学习总结之二:Lucene的总体架构
    Lucene学习总结之一:全文检索的基本原理
    解决Eclipse中文乱码
    【Lucene4.8教程之五】Luke
    【Tika基础教程之一】Tika基础教程
  • 原文地址:https://www.cnblogs.com/legion/p/8675014.html
Copyright © 2020-2023  润新知