Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities

Introduction to the

In the previous article, we used Netty to build a server capable of handling the WebSocket protocol. In this server, we built special handlers to handle HTTP or WebSocket requests.

Handling two different requests in one handler may be too much for some clean code freaks. Is it possible to use different handlers for normal HTTP requests and Websocket requests? The answer is yes.

Netty message processing

We know that all of the message processing in the netty are implemented through the handler, for convenience, netty provides a simple message processing class SimpleChannelInboundHandler, everyone through inheritance to rewrite channelRead0 method it can:

protected abstract void channelRead0(ChannelHandlerContext ctx, I msg) throws Exception;
Copy the code

We look at the definition of SimpleChannelInboundHandler:

public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter
Copy the code

Can see is with a generic I SimpleChannelInboundHandler itself, and that’s what we are going to discuss the direction of the I.

If we were to use this handler to handle all messages, we would value I as Object.

If we only need to process String messages, we can do this:

public class StringHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String message) throws Exception { System.out.println(message); }}Copy the code

Similarly, if you want to handle both HTTP and WebSocket messages, you simply set I to a different type.

For WebSocketFrame, we have:

public class Server2FrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> 
Copy the code

For FullHttpRequest, we have:

public class Server2HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> 
Copy the code

Processing WebSocketFrame

For WebSocketFrame messages, we know from the previous section that there are six types:

BinaryWebSocketFrame
CloseWebSocketFrame
ContinuationWebSocketFrame
PingWebSocketFrame
PongWebSocketFrame
TextWebSocketFrame
Copy the code

The ones that actually contain content are TextWebSocketFrame and BinaryWebSocketFrame, and here we treat TextWebSocketFrame specifically:

protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame) throws Exception {if (Frame Instanceof TextWebSocketFrame) {// Converts the received message into an uppercase String Request = ((TextWebSocketFrame) frame).text(); ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA))); } else {String message = "unsupported Frame type:" + frame.getClass().getName(); throw new UnsupportedOperationException(message); }}Copy the code

Handle the HTTP

For FullHttpRequest in HTTP request, we just install the normal HTTP service request processing flow.

I won’t go into too much detail here.

Encoders and decoders

Wait, did we forget something? Yeah, that’s code and decoder.

In the last section, we use the WebSocketServerHandshaker to websocket message encoding and decoding. But it’s actually in our custom Hadler code, which is a little bit inelegant to use.

It doesn’t matter, netty provides us with a WebSocketServerProtocolHandler class, responsible for websocket encoding and decoding problems.

In addition to processing of normal websocket handshake, WebSocketServerProtocolHandler class also dealt with the Close for us,, Ping Pong this several general message type. We just need to focus on the real business logic messages, which is very convenient.

Any remaining Text or Binary frame data is passed to the next handler in the pipline for processing.

Handshake has two states:

HANDSHAKE_COMPLETE and HANDSHAKE_TIMEOUT.

HandshakeComplete contains requestUri, requestHeaders, and selectedSubprotocol.

Finally, the WebSocketServerProtocolHandler join the pipeline, end up with:

    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new HttpObjectAggregator(65536));
        pipeline.addLast(new WebSocketServerCompressionHandler());
        pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
        pipeline.addLast(new Server2HttpHandler());
        pipeline.addLast(new Server2FrameHandler());
    }
Copy the code

conclusion

A server that separates HTTP requests from webSocket requests is complete. Simple and intuitive is a programmer’s world!

Learn -netty4 for an example of this article

This article is available at www.flydean.com/24-netty-we…

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!