Nettty的handler执行顺序

Handler在netty中,无疑占据着非常重要的地位。Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码、拦截指定的报文、统一对日志错误进行处理、统一对请求进行计数、控制Handler执行与否。一句话,没有它做不到的只有你想不到的。

Netty中的所有handler都实现自ChannelHandler接口。按照输出输出来分,分为ChannelInboundHandler、ChannelOutboundHandler两大类。ChannelInboundHandler对从客户端发往服务器的报文进行处理,一般用来执行解码、读取客户端数据、进行业务处理等;ChannelOutboundHandler对从服务器发往客户端的报文进行处理,一般用来进行编码、发送报文到客户端。

Netty中,可以注册多个handler。ChannelInboundHandler按照注册的先后顺序执行;ChannelOutboundHandler按照注册的先后顺序逆序执行,如下图所示,按照注册的先后顺序对Handler进行排序,request进入Netty后的执行顺序为:

 

 

先举一个例子吧

 bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        try {
            //NIO服务的辅助启动类
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .option(ChannelOption.SO_BACKLOG, 128)
             .option(ChannelOption.SO_KEEPALIVE, true)
             .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000*60*5)
             .handler(new LoggingHandler(LogLevel.DEBUG))//设置父类handler
             .childHandler(new ChannelInitializer<SocketChannel>(){
                 @Override
                 protected void initChannel(SocketChannel socketChannel) throws Exception {
                     ChannelPipeline pipeline = socketChannel.pipeline();
                     pipeline.addLast("idleHandler",new TIdleHandler(AdapterParam.READIDLE, AdapterParam.WRITEIDLE,  AdapterParam.ALLIDLE));
                     //解码器
                     pipeline.addLast("decoder", new TDecoder());
                     //编码器
                     pipeline.addLast("encoder", new TEncoder());
                     //业务处理器
                     pipeline.addLast("handler", new THandler());
                 }
              });
            b.bind(port).sync();

 

这里加了四个handler两个outbound handler(idlehander , encoder)和两个inbound handler(decoder , handler)  添加顺序分别为:

idlehandler , decoder , encoder , handler , 

那么inbound的handler执行顺序,也就是收到消息的执行顺序为decoder , handler ,inbound执行顺序为先添加先执行

outbound的handler执行顺序,也就是发送消息的执行顺序为 encoder , idlehandler ,outbound的执行顺序为先添加的后执行

曾经遇到一个问题,在心跳监测中,也就是idlehandler中用ctx发送消息,发现对端接收不到,后来才发现,ctx.writeandflush方法是执行下一个handler,按照这个handler添加顺序,那么久不会执行encoder ,所以消息可能会发送不出去,但是用channel发送消息是重新跑一边所有的outbound handler也就是说会先执行encoder,这样才能将消息发送出去

猜你喜欢

转载自dwj147258.iteye.com/blog/2401024