Nettty's handler execution order

Handler undoubtedly occupies a very important position in netty. The Handler is very similar to the filter in the Servlet. Through the Handler, you can complete the decoding and encoding of the communication message, intercept the specified message, uniformly process the log error, uniformly count the request, and control whether the Handler is executed or not. In a word, what you can't do without it is only what you can't think of.

All handlers in Netty implement the ChannelHandler interface. According to the output, it is divided into two categories: ChannelInboundHandler and ChannelOutboundHandler. ChannelInboundHandler processes the packets sent from the client to the server, and is generally used for decoding, reading client data, and performing business processing; ChannelOutboundHandler processes the packets sent from the server to the client, and is generally used for encoding, Send the message to the client.

In Netty, multiple handlers can be registered. ChannelInboundHandler is executed in the order of registration; ChannelOutboundHandler is executed in reverse order of registration, as shown in the following figure, the Handlers are sorted according to the order of registration, and the execution order after the request enters Netty is:

 

 

Let's take an example

bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        try {
            //Auxiliary startup class for NIO service
            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))//Set the parent class 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));
                     //decoder
                     pipeline.addLast("decoder", new TDecoder());
                     //Encoder
                     pipeline.addLast("encoder", new TEncoder());
                     // business handler
                     pipeline.addLast("handler", new THandler());
                 }
              });
            b.bind(port).sync();

 

Here, four handlers, two outbound handlers (idlehander, encoder) and two inbound handlers (decoder, handler) are added in the order of addition:

idlehandler , decoder , encoder , handler , 

Then the execution order of the inbound handler, that is, the execution order of the received message is decoder, handler, and the inbound execution order is add first and execute first

The execution order of outbound handlers, that is, the execution order of sending messages is encoder, idlehandler, and the execution order of outbound is added first and then executed

I once encountered a problem. In the heartbeat monitoring, that is, the idlehandler used ctx to send messages, and found that the peer could not receive it. Later, I found out that the ctx.writeandflush method is to execute the next handler. According to the order in which this handler is added, it will not take so long. The encoder will be executed, so the message may not be sent out, but to send the message with the channel is to rerun all the outbound handlers, that is to say, the encoder will be executed first, so that the message can be sent out

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326572514&siteId=291194637