This is the 11th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Introduction to the

Over the past series of articles, we’ve seen how Netty works, and we’ve introduced the basic netty service setup process and how to write a message handler. Today’s article introduces you to a more complex example, text chat rooms.

Chat room workflow

Today we are going to introduce text chat rooms. For text chat rooms, you first need to set up a server to handle the connections of each client. For clients, you need to set up a connection to the server and then enter chat messages to the server. After the server receives the chat message, it will respond to the message and return the message to the client, thus completing the process of a chat room.

Text processor

In the previous article, we mentioned that Netty transfers only support ByteBuf type, for chat room directly input strings are not supported, need to encode and decode strings.

The classes we introduced earlier for Encode and decode are called ObjectDecoder and ObjectEncoder. Today we will introduce two more StringDecoder and StringEncoder that deal specifically with strings.

StringEncoder is much simpler than ObjectEncoder, because for the object, we also need to set the size of the Byte array at the head of the Byte array to make sure that all the data in the object is read correctly. In the case of strings, it’s relatively simple. You just need to make sure that each read is a String.

StringEncoder inherits from MessageToMessageEncoder with the following core encode code:

    protected void encode(ChannelHandlerContext ctx, CharSequence msg, List<Object> out) throws Exception {
        if (msg.length() == 0) {
            return;
        }

        out.add(ByteBufUtil.encodeString(ctx.alloc(), CharBuffer.wrap(msg), charset));
    }
Copy the code

As you can see from the code above, the core is actually calling the byteBufutil.encodeString method, which converts String to ByteBuf.

For string encodings, we also need to define a range of encodings. For example, we need to know how many strings to encode at a time. Generally, we use carriage returns to define the end of a string input.

Netty provides such very convenient also called DelimiterBasedFrameDecoder, by passing in different Delimiter, we can enter into different Frame, thus to deal with a line of string.

new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()))

Copy the code

Let’s look at the core of StringDecoder. StringDecoder inherits from MessageToMessageDecoder:

    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        out.add(msg.toString(charset));
    }
Copy the code

By calling the toString method of ByteBuf, BuyteBuf is converted to a string and output to the channel.

Initialize the ChannelHandler

When initChannel is used, we need to add a valid Handler to ChannelPipeline. For this example, you need to add StringDecoder, StringEncoder, DelimiterBasedFrameDecoder and custom handler of real process the message.

We put all the initializers in a new ChatServerInitializer class. This class inherits from ChannelInitializer. Its core initChannel method is as follows:

public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); / / add the line segmentation pipeline. AddLast (new DelimiterBasedFrameDecoder (8192, Delimiters. LineDelimiter ())); // Add String Decoder and String Encoder for String conversion pipeline. AddLast (Decoder); pipeline.addLast(ENCODER); // Finally add the actual handler pipeline.addlast (SERVER_HANDLER); }Copy the code

ChatServerInitializer is added to childHandler in Bootstrap.

childHandler(new ChatServerInitializer())
Copy the code

Real message processing logic

With the above logic in place, we finally just need to focus on the real message processing logic.

Our logic here is to close the channel when the client enters “goodbye”, otherwise send the message back to the client.

The core logic is as follows:

public void channelRead0(ChannelHandlerContext ctx, String Request) throws Exception {// Close channel String Response if "goodbye" is read; Boolean close = false; If (request.isempty ()) {response = "What did you say? \r\n"; } else if (" good-bye ".equalsignorecase (request)) {response = "good-bye, my friend! \r\n"; close = true; } else {response = "did you say: '" + request + "'? \r\n"; } // Write the message. ChannelFuture Future = ctx.write(response); / / add CLOSE listener, which is used to CLOSE the channel if (CLOSE) {future. AddListener (ChannelFutureListener. CLOSE); }}Copy the code

By judging the client, whether to set up the CLOSE button to CLOSE the channel here is to add ChannelFutureListener ChannelFuture. CLOSE.

ChannelFutureListener. CLOSE is a ChannelFutureListener, it can be carried in the channel after CLOSE the channel, in fact this is a very elegant way of closing.

ChannelFutureListener CLOSE = new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { future.channel().close(); }};Copy the code

For the client, the core is to read input from the command line, which is received with the InputStreamReader and cached with the BufferedReader.

Then write the command line input to the channel by calling ch.writeandFlush, and listen for the command line input. If “goodbye” is heard, wait for the server to close the channel. The core code is as follows:

// From the command line, enter ChannelFuture lastWriteFuture = null; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); for (;;) { String line = in.readLine(); if (line == null) { break; } lastWriteFuture = ch.writeAndFlush(line + "\r\n"); If (" good-bye ".equalsignoRecase (line)) {ch.closeFuture().sync(); break; } // Wait for all messages to be written to the channel if (lastWriteFuture! = null) { lastWriteFuture.sync(); }Copy the code

conclusion

After the above introduction, a simple chat room was built. We’ll explore more complex applications in the future, and I hope you enjoy them.

An example for this article is learn-Netty4

This article is available at www.flydean.com/10-netty-ch…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many you do not know the small skills waiting for you to find!

Welcome to follow my public number: “procedures those things”, understand technology, more understand you!