zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    bbb SOCKET CAN
    在BBB上使用CCS5开发环境
    BBB的PRU模块
    垃圾邮件分类
    yzoj 2377 颂芬梭哈 题解
    yzoj 2372 小B的数字 题解
    yzoj P2371 爬山 题解
    hdu 1007 Quoit Design 题解
    手写堆
    yzoj P1126 塔 题解
  • 原文地址:https://www.cnblogs.com/legion/p/8675014.html
Copyright © 2011-2022 走看看