[Netty] Netty core component (analysis of the two-way linked list of ChannelHandlerContext in ChannelPipeline)

Article catalog



Next blog [Netty] Netty core component (Pipeline | ChannelPipeline) Content, in debug debugging, detailed analysis of channel pipeline internal Handler two-way linked list;





1, Code example analysis


1. Based on the following code analysis:

// 1. Create two thread pools of bossGroup workerGroup before 
// Omit 10000 lines of code

// 2. To start the server object, you need to configure various parameters for the object
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup) // Set the master-slave thread group, corresponding to the master and slave reactors respectively
        .channel(NioServerSocketChannel.class)  // Set NIO network socket channel type
        .option(ChannelOption.SO_BACKLOG, 128)  // Set the number of connections maintained by thread queue
        .childOption(ChannelOption.SO_KEEPALIVE, true)  // Set connection state behavior, keep connection state
        
        // Core analysis code------------------------------------------------------------------------
        .childHandler(  // Set the corresponding event Handler for the NioEventLoop corresponding to the WorkerGroup thread pool
                new ChannelInitializer<SocketChannel>() {// Create channel initialization object
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // This method will call back after the connection between the server and the client is established successfully
                        // Get pipeline
                        ChannelPipeline pipeline = ch.pipeline();
                        // Add HTTP protocol codec HttpServerCodec to the pipeline,
                        // co in co dec means coder encoder, dec means coder decoder
                        // The first string is the name of the codec
                        pipeline.addLast("HttpServerCodec" , new HttpServerCodec());
                        // Setting up processor Hanedler for Pipeline
                        pipeline.addLast("HTTPServerHandler", new HTTPServerHandler());
                        // Pipeline initialization complete
                        // Break point on this line of code----------------------------------------------
                        System.out.println("Pipeline initialization complete!");
                    }
                }
               
        );
         // Core analysis code------------------------------------------------------------------------


2. Element type:


① Head and tail elements: the head and tail elements of the two-way linked list are automatically generated, with the type of DefaultChannelPipeline, and no Handler handler is encapsulated in the head and tail elements;

② Intermediate element: the intermediate element of the bidirectional linked list is of DefaultChannelHandlerContext type, which encapsulates the Handler processor;



3. The type of ChannelHandler encapsulated in the bidirectional linked list element: from the first element after the first element to the last element, each element in the bidirectional linked list is encapsulated with a ChannelHandler;



4. 333 Handler processors are put into the channelpipeline pipeline;


① ChannelInitializer: channel initializer;

② Httpservercodec: http server codec;

③ HTTP server handler: user-defined HTTP server business logic processor;



5. Channelpipeline pipeline add ChannelHandler processor:


① addFirst: add the ChannelHandler processor to the header of the bidirectional linked list;

ChannelPipeline addFirst(String name, ChannelHandler handler);
ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);

② addLast: add the ChannelHandler processor to the end of the bidirectional linked list;

ChannelPipeline addLast(String name, ChannelHandler handler);
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);




2, ChannelHandlerContext double linked list type


1. Header element and footer element types: the header element and footer element of a two-way linked list are of the DefaultChannelPipeline type, which does not encapsulate the ChannelHandler processor;


2. Intermediate type of bidirectional linked list: the header and footer intermediate type is DefaultChannelHandlerContext type, which encapsulates ChannelHandler processor;


3. Channelhandlercontext type:

final class DefaultChannelHandlerContext extends AbstractChannelHandlerContext {
    private final ChannelHandler handler;
    
    DefaultChannelHandlerContext(
            DefaultChannelPipeline pipeline, EventExecutor executor, String name, ChannelHandler handler) {
        super(pipeline, executor, name, isInbound(handler), isOutbound(handler));
        if (handler == null) {
            throw new NullPointerException("handler");
        }
        this.handler = handler;
    }

    @Override
    public ChannelHandler handler() {
        return handler;
    }

    private static boolean isInbound(ChannelHandler handler) {
        return handler instanceof ChannelInboundHandler;
    }

    private static boolean isOutbound(ChannelHandler handler) {
        return handler instanceof ChannelOutboundHandler;
    }
}




3, Analysis of bidirectional linked list in Pipeline / ChannelPipeline


0. Head (the 000th element): open the member of the head element to view its member composition;


① Prev is empty: This is the header of the two-way linked list, so its prev element (the previous element) is empty;

② Next element: view its next element. The next element must be of ChannelHandlerContext type;

③ Start header element type: DefaultChannelPipeline;

1. The 111th element Handler type of bidirectional linked list: its Handler is the anonymous inner class ChannelInitializer in HTTP server, that is, the created ChannelInitializer anonymous inner class;

The 111th element Handler type: ChannelInitializer, which inherits the channelinboundhandler adapter, so it is also a Handler;

public abstract class ChannelInitializer<C extends Channel> extends ChannelInboundHandlerAdapter



2. The 222th element Handler type of the two-way list: its Handler is an object of HttpServerCodec type, that is, the HttpServerCodec codec added for ChannelPipeline;

222th element Handler type: HttpServerCodec;

// Get pipeline
ChannelPipeline pipeline = ch.pipeline();

// Core code of this example---------------------------------------------
// Add HTTP protocol codec HttpServerCodec to the pipeline,
// co in co dec means coder encoder, dec means coder decoder
// The first string is the name of the codec
pipeline.addLast("HttpServerCodec" , new HttpServerCodec());
// Core code of this example---------------------------------------------



3. The 333th element Handler type of the two-way linked list: its Handler is an object of httpserverhandler type, that is, the httpserverhandler business logic processor added for ChannelPipeline;


① 333th element Handler type: HttpServerHandler;

② HTTPServerHandler class structure: where HTTPServerHandler inherits simplechannelinboundhandler < httpobject >;

public class HTTPServerHandler extends SimpleChannelInboundHandler\<HttpObject\>

③ The corresponding code to add the HTTPServerHandler handler to the pipeline:

new ChannelInitializer<SocketChannel>() {// Create channel initialization object
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        // This method will call back after the connection between the server and the client is established successfully
        // Get pipeline
        ChannelPipeline pipeline = ch.pipeline();
        // Add HTTP protocol codec HttpServerCodec to the pipeline,
        // co in co dec means coder encoder, dec means coder decoder
        // The first string is the name of the codec
        pipeline.addLast("HttpServerCodec" , new HttpServerCodec());
        
        // Core code of this example---------------------------------------------
        // Setting up processor Hanedler for Pipeline
        pipeline.addLast("HTTPServerHandler", new HTTPServerHandler());
        // Core code of this example---------------------------------------------
        
        // Pipeline initialization complete
        System.out.println("Pipeline initialization complete!");
    }
}



4. The 444th element of the two-way linked list: the fourth element is also the end of the two-way linked list. The type is the same as the type of the head element of the linked list, which is DefaultChannelPipeline;


① The 444th element type: DefaultChannelPipeline;

② Next is empty: its next is empty, indicating that the element is the end of the two-way linked list;





4, Data inbound and outbound


1. Data inbound and outbound operations corresponding to bidirectional linked list:


① Data transfer in a linked list: in a two-way linked list, data is transferred in two directions: inbound and outbound;

② Inbound data: transfer data from the header of the linked list to the tail of the linked list, and transfer the data one by one to the Handler. The Handler in each linked list element processes the data accordingly;

③ Outbound data: transfer data from the end of the linked list to the header, and process the data accordingly through each Handler;



Take the above code example for analysis



2. Inbound operation in the example:


① Initialization of two-way linked list: the client requests the server-side resources. After the client requests, the two-way linked list of the ChannelHandlerContext is initialized first, and put into three ChannelHandler channel processors: channelinitializer, httpservercodec and httpserverhandler;

② Data decoding: when the client requests data, it first passes it to the HttpServerCodec server codec server for processing, where the data needs to be decoded;

③ Business logic: then input the data output by HttpServerCodec to the user-defined http serverhandler for processing;

Tags: codec Netty network socket

Posted on Sun, 07 Jun 2020 01:58:43 -0700 by hank__22