Introduction to Netty (1): Detailed graphic steps of zero-based "HelloWorld"

Because the next project will use netty, so let's learn about this program. However, the tutorials on the Internet are a little basic, so I will write a zero-based article on netty and record it by the way.

 

First throw a few reference learning pages: 

Netty official API:  http://netty.io/4.1/api/index.html

netty Chinese guide: https://waylau.com/netty-4-user-guide/    (from personal)

 

Knowledge about NIO basics: https://my.oschina.net/andylucci/blog/614295

            http://www.cnblogs.com/dolphin0520/p/3919162.html 

          http://blog.csdn.net/wuxianglong/article/details/6604817  

What I use here:

netty version: netty-5.0.0.Alpha2  http://files.cnblogs.com/files/applerosa/netty-5.0.0.Alpha2.7z

maven dependencies:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>5.0.0.Alpha2</version>
</dependency>

 

 

Alright, let's get started.

1. First of all, you need to build a java project. As for a common project or a maven project, it depends on your preferences. Because I am just here for learning, I built a common project, and then threw the downloaded jar package into lib, and imported it Can.

  

Second, next we have to figure out what netty is.

  The official introduction is: Netty is a java open source framework provided by JBOSS . Netty provides an asynchronous, event-driven network application framework and tools for rapid development of high-performance, high-reliability network server and client programs.

  Then let's briefly understand, this thing is a program, what does it do? Netty encapsulates java socket noi. A similar function is apache's mina.

  Compared with Tomcat, a Web Server (as the name implies, it mainly provides services related to Web protocols), Netty is a Network Server, which is a network framework at the lower level of Web Server, which means that you can use Netty to imitate Tomcat to provide HTTP services. web container.

  

  To put it bluntly, it is a good thing to deal with Socket. If you want to know more details, you can go to the official introduction.

  

3. Back to the topic, we start to write the so-called "Hello World"

  Insert here, that is, our communication is based on a certain protocol, such as our commonly used Web projects, the foreground (browser) sends a request, and the background makes a corresponding response and returns the corresponding result, the process of this communication is also It is so.

  In the official netty guide, it is said that the simplest protocol in the world is not 'Hello, World!' but  DISCARD (discard service) . This protocol will discard any received data without responding. That is, your client sends a message, well, it has been sent, and the server has also received it, but discarded it.

  To put it bluntly, you sent me a message and I received it, but I just discarded the message and ignored you.

   

Secondly, about netty, we must first figure out that this is established between the client and the server.

 

 

 

Let's talk about the server first. The server establishes the corresponding rules, and then runs it, waiting for the client to access or send a "message". Well, let's create the server-side code first:

 

The first step: first establish the corresponding rules :

copy code
package _01discard;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;

/**
 * The server handles the channel. Here is just to print the content of the request, and does not respond to the request. DiscardServerHandler inherits from
 * ChannelHandlerAdapter, this class implements the ChannelHandler interface, ChannelHandler provides many interface methods for event processing,
 * Then you can override these methods. Now just subclass the ChannelHandlerAdapter class instead of implementing the interface methods yourself.
 *
 */
public class DiscardServerHandler extends ChannelHandlerAdapter {
    /**
     * Here we override the chanelRead() event handler method. Whenever new data is received from the client, this method will be called when a message is received,
     * In this example, the type of the received message is ByteBuf
     *
     * @param ctx
     * Context information for channel processing
     * @param msg
     * Received message
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {

        try {
            ByteBuf in = (ByteBuf) msg;
            // Print the client input, the transmitted characters
            System.out.print(in.toString(CharsetUtil.UTF_8));
        } finally {
            /**
             * ByteBuf is a reference counted object that must be released explicitly by calling the release() method.
             * Remember that the processor's responsibility is to free all reference-counted objects passed to the processor.
             */
            // discard the received data
            ReferenceCountUtil.release(msg);
        }

    }

    /***
     * This method will be triggered when an exception occurs
     *
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        /**
         * The exceptionCaught() event handling method is called when the Throwable object appears, that is, when Netty is due to IO
         * On errors or exceptions thrown by the handler while handling the event. In most cases, caught exceptions should be logged and the associated channel
         * to turn off. However, the way this method is handled will be implemented differently in the case of different exceptions. For example, you may want to send a response message with an error code before closing the connection.
         */
        // close on exception
        cause.printStackTrace();
        ctx.close();
    }

}
copy code

Step 2: We need to apply the corresponding rules. That is to say, we have established rules for receiving messages, but what is the use of establishing rules, it is just a rule, we need to "apply" this rule, which is usually our usual "run".

copy code
package _01discard;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * Discard any incoming data to start the DiscardServerHandler on the server
 */
public class DiscardServer {
    private int port;

    public DiscardServer(int port) {
        super();
        this.port = port;
    }

    public void run() throws Exception {

        /***
         * NioEventLoopGroup is a multi-threaded event looper used to handle I/O operations,
         * Netty provides many different EventLoopGroup implementations to handle different transport protocols. In this example we implement a server-side application,
         * Therefore, 2 NioEventLoopGroups will be used. The first is often called the 'boss' and is used to receive incoming connections.
         * The second one, often called 'worker', handles connections that have already been received, and once 'boss' receives a connection, it registers the connection information with 'worker'.
         * How to know how many threads have been used and how to map to the created Channels all depend on the implementation of EventLoopGroup,
         * and their relationship can be configured through the constructor.
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        System.out.println("Ready to run port: " + port);
        try {
            /**
             * ServerBootstrap is an auxiliary startup class that starts NIO services. You can use Channel directly in this service
             */
            ServerBootstrap b = new ServerBootstrap();
            /**
             * This step is required, if the group is not set, it will report java.lang.IllegalStateException: group not
             * set exception
             */
            b = b.group(bossGroup, workerGroup);
            /***
             * ServerSocketChannel is implemented based on NIO's selector to receive new connections
             * Here tells Channel how to get new connections.
             */
            b = b.channel(NioServerSocketChannel.class);
            /***
             * The event handler class here is often used to handle a recently received Channel. ChannelInitializer is a special processing class,
             * His purpose is to help users configure a new Channel.
             * Maybe you want to configure a new Channel by adding some handler classes like NettyServerHandler
             * Or its corresponding ChannelPipeline to implement your network program. When your program becomes more complex, you may add more processing classes to the pipline,
             * Then extract these anonymous classes to the top-level class.
             */
            b = b.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new DiscardServerHandler());// demo1.discard
                    // ch.pipeline().addLast(new
                    // ResponseServerHandler());//demo2.echo
                    // ch.pipeline().addLast(new
                    // TimeServerHandler());//demo3.time
                }
            });
            /***
             * You can set configuration parameters for the channel implementation specified here. We are writing a TCP/IP server,
             * So we are allowed to set socket parameter options like tcpNoDelay and keepAlive.
             * Please refer to the interface documentation of ChannelOption and detailed ChannelConfig implementation to have a general understanding of ChannelOptions.
             */
            b = b.option(ChannelOption.SO_BACKLOG, 128);
            /***
             * option() is provided to NioServerSocketChannel to receive incoming connections.
             * childOption() is provided to the connection received by the parent pipe ServerChannel,
             * Also NioServerSocketChannel in this example.
             */
            b = b.childOption(ChannelOption.SO_KEEPALIVE, true);
            /***
             * Bind the port and start to receive incoming connections
             */
            ChannelFuture f = b.bind(port).sync();
            /**
             * This will wait until the socket is closed
             */
            f.channel().closeFuture().sync();
        } finally {
            /***
             * closure
             */
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
  

   //run the rule public static void main(String[] args) throws Exception { int port; if (args.length > 0) { port = Integer.parseInt(args[0]); } else { port = 8080; } new DiscardServer(port).run(); System.out.println("server:run()"); } }
copy code

 

Step 3: We now have the corresponding rules established, and the code for "running" the rules is OK, so run the above    public static void main(String[] args) to start the server.

  

At this point, the server is already running and is in a state of waiting for access.

 

 

client

Because this is a simple demo, we use telnet as a client. Of course, the project must be customized according to needs.

First open the terminal, I am the windows system here, take this as an example, open the cmd window;

  

  Type   telnet 127.0.0.1 8080 and press Enter to enter the telnet terminal

  

 

  To add here, the win system does not open the telnet client by default. If you need it, go to Control Panel >> Programs >> Turn on or turn off the windows function and check it, as shown below.

  

 

 

Well, at this step of the telnet client, you can test the message

In addition, the default telnet client input is not displayed, but anyway, if the console has output after input, it means that your process has run through. Such as:

 

 You also use ctrl+] in the terminal to display, like:

 

 

 

Come here, what the whole process is like, I have a number in my heart, and then just like learning the ordinary framework, let’s start the advanced road.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325630480&siteId=291194637