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

 

posted on 2018-03-30 10:57  legion  阅读(566)  评论(0编辑  收藏  举报

导航