SoFunction
Updated on 2025-03-03

Example of SpringBoot's method of integrating Netty server

Work scenario: Use Netty long connection to obtain vehicle positioning data of third-party interfaces in real time

Development environment: JDK8

Netty basic introduction

1. What is Netty

Netty is a Java open source framework provided by JBOSS, now a standalone project on Github. It is an asynchronous event-driven network application framework for rapid development of high-performance and high-reliability network IO programs. Netty is mainly aimed at high concurrent applications for Clients under the TCP protocol, or applications where large amounts of data are continuously transmitted in the Peer-to-Peer scenario.

Netty provides a complete set of APIs for handling network IO operations such as TCP and UDP sockets. It encapsulates the underlying network programming details, allowing developers to focus more on the implementation of business logic. Netty uses an efficient threading model that can handle a large number of concurrent connections and is very scalable.

Netty has a wide range of applications in many fields, such as RPC framework, gaming industry, big data field, etc. It supports a variety of transport types and protocols, such as blocking and non-blocking, UDP transport based on BIO and NIO, local transport (in-VM transport), HTTP channels, etc. At the same time, Netty also provides a rich codec for handling codec operations of various protocols.

Netty's overall structure includes the core layer and the protocol support layer. The core layer provides a common abstraction and implementation of underlying network communication, including a scalable event model, a common communication API, ByteBuf that supports zero copy, etc. The protocol support layer covers the encoding and decoding implementation of mainstream protocols, such as HTTP, SSL, Protobuf, etc.

Overall, Netty is a powerful and easy-to-use network application framework that can help developers quickly build high-performance and high-reliability network applications.

2. Netty core components

Netty's core components mainly include the following parts:

  • Channels: Channel is an abstraction of Netty network communications and is used for I/O operations. It can be regarded as a basic abstraction of Java NIO, representing an open connection with hardware devices, files, network sockets and other entities, or a program that can complete I/O operations such as reading and writing. Channels can be opened or closed, connected or disconnected.
  • Callbacks (callback): Callback is a method that is a reference provided to another method, so that another method can go back and call the Callback method at appropriate times. Callback is widely used in many programming situations and is one of the most commonly used methods to notify relevant parties that an operation has been completed.
  • Futures: In Netty, Futures is used for the results of asynchronous I/O operations. When an asynchronous operation starts, a Future will be returned immediately, which will get a result or an exception when the operation is completed.
  • Handlers: Handlers are components in Netty that handle I/O events or intercept I/O operations. Netty provides many built-in Handlers, such as ChannelInboundHandler, ChannelOutboundHandler, etc. These Handlers can handle various I/O events, such as connection establishment, data reception, exception handling, etc.
  • Bootstrap vs. ServerBootstrap: Bootstrap and ServerBootstrap are boot classes of Netty programs, mainly used to configure various parameters and start the entire Netty service. They all inherit from the AbstractBootstrap abstract class. The difference is that Bootstrap is used for client booting, while ServerBootstrap is used for server booting.
  • EventLoopGroup: EventLoopGroup can be understood as a thread pool used to handle I/O operations. In server programs, two EventLoopGroups are generally bound, one is used to handle Accept events (i.e., a new connection request), and the other is used to handle read and write events.

The above components together form Netty's core framework, allowing developers to focus more on the implementation of business logic without having to pay too much attention to the underlying network communication details.

3. Integration of SpringBoot and Netty

1. Add dependencies

In the SpringBoot project file, we need to add Netty's dependencies. Netty's official Maven warehouse address is: /artifact//netty-all

    <dependencies>
        <!-- mybatis-plus -->
        <dependency>
            <groupId></groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!-- Mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--   Data Source     -->
        <dependency>
            <groupId></groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>

        <!--   netty     -->
        <dependency>
            <groupId></groupId>
            <artifactId>netty-all</artifactId>
        </dependency>

        <dependency>
            <groupId></groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <dependency>
            <groupId></groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId></groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>${}</version>
        </dependency>

    </dependencies>

2. Create Netty server

@Component
public class NettyServer {

    //Responsible for handling accepted links    private EventLoopGroup bossGroup;
    //Responsible for handling I/O operations on the already received connection    private EventLoopGroup workerGroup;
    //In this scenario, it represents the result of the binding operation of the server    private ChannelFuture future;

    @PostConstruct
    public void startServer() throws Exception {
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        try {
            //Create ServerBootstrap, this class encapsulates the server-side network configuration, allowing us to easily set server parameters            ServerBootstrap bootstrap = new ServerBootstrap();
            (bossGroup, workerGroup)
                    .channel()
                    .childHandler(new NettyServerInitializer());

            // Bind the port and start accepting incoming connections            future = (7000).sync();

            // Wait for the server socket to close            ().closeFuture().sync();
        } finally {
            ();
            ();
        }
    }

    @PreDestroy
    public void stopServer() {
        if (future != null && !()) {
            (true);
        }
        ();
        ();
    }
}

Code parsing

Class annotation

  • @Component: This is annotation of the Spring framework, indicating that this class is a component, Spring will scan to this class and register it as a bean into the Spring container. Therefore, this class can be automatically assembled by other Spring-managed beans (if needed).

Class member variables

  • bossGroupandworkerGroup: These two areEventLoopGroupAn instance of the process of network events.bossGroupMainly responsible for receiving incoming connections, andworkerGroupResponsible for handling I/O operations on the already received connection.
  • future: This is aChannelFutureThe example of the , represents the result of an asynchronous I/O operation. In this scenario, it represents the result of the binding operation of the server.

startServer method

  • This method uses@PostConstructAnnotation, which means that this method will be called automatically when the Spring container instantiates the bean and completes dependency injection.
  • In this method, two are created firstNioEventLoopGroupExamples, one for boss and one for worker.
  • Then, useServerBootstrapClass to configure and start the server. This class encapsulates the server-side network configuration, allowing us to easily set server parameters.
  • passgroupMethods to set boss and workerEventLoopGroup
  • passchannelMethod Specify UseNioServerSocketChannelImplemented as a channel for the server.
  • passchildHandlerHow to deal with a new connection after it is accepted. Used hereNettyServerInitializer(This class is not defined in the provided code snippet, but we can assume that it is aChannelInitializerImplementation for configuring newChannel)。
  • usebindMethod binds the server to the specified port (here is 7000) and usessyncThe method blocks until the binding is complete.
  • Finally, usecloseFuture().sync()The method blocks the current thread until the server socket is closed.
  • existfinallyIn the block, it will be closed gracefully regardless of whether an exception occurs or not.EventLoopGroup

stopServer method

  • This method uses@PreDestroyAnnotation means that this method will be automatically called before the Spring container destroys the bean.
  • In this method, first checkfutureWhether it has been completed (i.e. whether the server has been shut down). If not, callcancel(true)Method to try to cancel this operation. However, it should be noted thatcancelIt may not always be possible to stop the server immediately, it is more about trying to stop the server than forcing it to stop.

3. Create a character parser to parse received messages

public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch){
        ChannelPipeline pipeline = ();

        // Add a string decoder to convert the received ByteBuf into a string        // Assume here is using the UTF-8 character set        ("decoder", new StringDecoder(CharsetUtil.UTF_8));

        // Add a string encoder to convert the sent string into ByteBuf        // In this way, when the server sends a string, the client can directly receive the string        ("encoder", new StringEncoder(CharsetUtil.UTF_8));

        // Add a custom ChannelInboundHandlerAdapter to handle business logic        ("handler", new MyChannelHandler());
    }
}

This code defines aNettyServerInitializerclass, it inherits fromChannelInitializer<SocketChannel>, and coveredinitChannelmethod. In Netty,ChannelInitializerIt is a special processor, its main purpose is to help users configure a new oneChannelofChannelPipeline. Netty will automatically call when a new connection is acceptedChannelInitializerofinitChannelMethod to set this new connectionChannelPipeline

Specifically,initChannelThe method will be called in the following cases:

  • whenServerBootstrapofbindAfter the method is called and successfully bound to a port, it starts listening for incoming connections.
  • Once a client is connected to the server,ServerBootstrapWill accept this connection and create a new oneSocketChannelto represent this connection.
  • For this newSocketChannelNetty will call the previously setChannelInitializer(In this example,NettyServerInitializer)ofinitChannelmethod.
  • initChannelThis new method will be configured internallySocketChannelofChannelPipeline, add decoder, encoder, service processor, etc.
  • onceinitChannelThe method has been executed, thisChannelInitializerThe mission is completed and will be completed fromChannelPipelineremove itself because it is only responsible for initialization and does not participate in subsequent data processing.

So, in summary,NettyServerInitializerofinitChannelThe method will be run when a new client connection is accepted by the server and is used to initialize the new connection.ChannelPipeline

4. Create a Handler to process the received message

public class MyChannelHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // Process the received data here

        ("msg = " + msg);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // Handle exceptions here    }
}

4. Problems encountered during development (not yet solved)

1. After the character parser is defined, the received message is still garbled

2. After the project is started, you can access the netty port number, but the project port number cannot be accessed (solved)

// ().closeFuture().sync(); just block this code

This is the end of this article about SpringBoot integrating Netty server. For more related content related to SpringBoot integrating Netty server, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!