Introduction to the

In the previous article, we introduced the support of multiple different services in the same Netty program. Its logic is very simple, that is, it starts multiple subroutines in a main program, and each subroutine binds different ports through a BootStrap, so as to access different services through different ports.

However, although multiple ports are highly differentiated, they are still inconvenient to use. Is it possible to use only one port to unify different protocol services?

Today I’m going to show you the method of running different protocols on the same port in Netty. This method is called Port Unification.

SocksPortUnificationServerHandler

In the interpretation of the custom port before unification, we’ll look at port of netty bring unification, such as SocksPortUnificationServerHandler.

We know that there are three main protocols for SOCKS, namely SOCKS4, SOCKS4a, and SOCKS5, which belong to different versions of the same protocol. Therefore, different ports cannot be used, and the version must be determined on the same port.

Specifically, SocksPortUnificationServerHandler inherited from ByteToMessageDecoder, said is an object will be converted into corresponding ByteBuf Socks.

So how does he tell the different versions apart?

In the decode method, the ByteBuf in to decode is passed in, and its readerIndex is first obtained:

int readerIndex = in.readerIndex();
Copy the code

We know that the first byte of the SOCKS protocol represents the version, so read the first byte from in ByteBuf as the version number:

byte versionVal = in.getByte(readerIndex);
Copy the code

Have version number can be processed by different version number, specifically, for SOCKS4a, need to add Socks4ServerEncoder and Socks4ServerDecoder:

case SOCKS4a:
            logKnownVersion(ctx, version);
            p.addAfter(ctx.name(), null, Socks4ServerEncoder.INSTANCE);
            p.addAfter(ctx.name(), null, new Socks4ServerDecoder());
            break;
Copy the code

Need to add for SOCKS5 Socks5ServerEncoder and Socks5InitialRequestDecoder two coding and decoder:

case SOCKS5:
            logKnownVersion(ctx, version);
            p.addAfter(ctx.name(), null, socks5encoder);
            p.addAfter(ctx.name(), null, new Socks5InitialRequestDecoder());
            break;
Copy the code

In this way, a port unification is completed. The idea is to determine the version number of SOCKS through the first byte of ByteBuf of the same port, so that different SOCKS versions can be processed.

Custom PortUnificationServerHandler

In this example, we will create a custom Port Unification to receive both HTTP requests and GZIP requests.

Before that, let’s take a look at the magic Word of two protocols, that is, we get a ByteBuf, how can we know this is an HTTP protocol, or a gzip file transfer?

Let’s take a look at the HTTP protocol. The default is HTTP1.1. Here’s an example of the HTTP request protocol:

GET/HTTP/1.1 Host: www.flydean.comCopy the code

The first word of an HTTP request is the name of the HTTP request method. Specifically, there are eight methods:

OPTIONS returns HTTP request methods supported by the server for a particular resource. You can also test the functionality of the server by sending ‘*’ requests to the Web server. The HEAD asks the server for a response that matches the GET request, except that the response body will not be returned. This method allows you to retrieve the meta information contained in the response header without having to transfer the entire response content. GET makes a request to a specific resource. Note: The GET method should not be used for operations that cause “side effects,” such as in Web Applications. One reason is that GET can be accessed randomly by web spiders and so on. POST Submits data to a specified resource for processing requests (such as submitting a form or uploading a file). The data is contained in the request body. POST requests may result in the creation of new resources and/or the modification of existing resources. PUT uploads its latest content to the specified resource location. DELETE Requests the server to DELETE the resource identified by request-URI. TRACE displays the requests received by the server for testing or diagnosis. CONNECT Reserved in HTTP/1.1 for proxy servers that can pipe connections.

So how many bytes does it take to distinguish between these eight methods? You can see that one byte is not enough, because we have POST and PUT, and their first byte is both P. So 2 bytes should be used for magic Word.

It also has a special format for the Gzip protocol, where the first 10 bytes of gzip are headers, where the first byte is 0x1f and the second byte is 0x8b.

So we can distinguish gZIP protocol with two bytes.

That’s where our handler logic comes in. First extract the first two bytes from byteBuf and then evaluate them to distinguish between HTTP requests and GZIP requests:

private boolean isGzip(int magic1, int magic2) { return magic1 == 31 && magic2 == 139; } private static boolean isHttp(int magic1, int magic2) { return magic1 == 'G' && magic2 == 'E' || // GET magic1 == 'P' && magic2 == 'O' || // POST magic1 == 'P' &&  magic2 == 'U' || // PUT magic1 == 'H' && magic2 == 'E' || // HEAD magic1 == 'O' && magic2 == 'P' || // OPTIONS magic1 == 'P' && magic2 == 'A' || // PATCH magic1 == 'D' && magic2 == 'E' || // DELETE magic1 == 'T' && magic2 == 'R' || // TRACE magic1 == 'C' && magic2 == 'O'; // CONNECT }Copy the code

For gzip, netty provides ZlibCodecFactory:

p.addLast("gzipEncoder", ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
p.addLast("gzipDecoder", ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
Copy the code

For HTTP, Netty also provides HttpRequestDecoder, HttpResponseEncoder, and HttpContentCompressor to encode and compress HTTP messages.

p.addLast("decoder", new HttpRequestDecoder());
p.addLast("encoder", new HttpResponseEncoder());
p.addLast("compressor", new HttpContentCompressor());
Copy the code

conclusion

After adding codecs and decoders, if you want to customize some operations, you just need to add custom corresponding message handlers, which is very convenient.

Learn -netty4 for an example of this article

This article is available at www.flydean.com/38-netty-cu…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!

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