WebSocket - Netty server construction
Article catalogue |
---|
Online websocket test - online tool postjson (coolaf. Com) |
In depth exploration of WebSocket protocol - cloud + community - Tencent cloud (tencent.com) |
/ |
1, WebSocket
Preliminary summary of a few words
- Is a full duplex communication protocol over a single TCP connection
- Only one handshake is needed between the server and the client to create a persistent connection for two-way data transmission
Difference between WebSocket and Socket
- Socket: active request from the client, passive response from the server, one-way data transmission;
- WebSocket: full duplex mode, only one handshake is required;
In fact, the scenarios used by WebSocket are those with high real-time requirements.
2, Building WebSocket server based on Netty
The WebSocket of the client will not be demonstrated, but only the server
2.1 introduction cases
NettyServer basic configuration
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; /** * @author Li Jiamin */ public class NettyServer { public void ServerStart() throws InterruptedException { // Connection request processing EventLoopGroup bossGroup = new NioEventLoopGroup(3); // IO request processing EventLoopGroup workerGroup = new NioEventLoopGroup(5); // Basic configuration ServerBootstrap serverBootstrap = new ServerBootstrap().group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); // Processor pipeline configuration serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { System.out.println("At this point, the client comes in:" + "customer SocketChannel hashcode=" + ch.hashCode()); ChannelPipeline pipeline = ch.pipeline(); // Request / response codec pipeline.addLast(new HttpServerCodec()); // Convert multiple messages into a single request / response object and decode it into FullHttpRequest // maxContentLength – maximum length of aggregated content in bytes pipeline.addLast(new HttpObjectAggregator(65535)); // WebSocket protocol processing pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); // The following is the customized WebSocket business processor pipeline.addLast(new WebSocketDemoHandler()); } }); // Server port configuration and monitoring ChannelFuture channelFuture = serverBootstrap.bind(16668).sync(); channelFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (channelFuture.isSuccess()) { System.out.println("Listening port 16668 succeeded"); } else { System.out.println("Listening port 16668 failed"); } } }); // Close the channel and listen channelFuture.channel().closeFuture().sync(); bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }
WebSocketDemoHandler business processor
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketFrame; /** * @author Li Jiamin */ public class WebSocketDemoHandler extends SimpleChannelInboundHandler<WebSocketFrame> { @Override protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception { if (msg instanceof TextWebSocketFrame) { // messages receiving String requestStr = ((TextWebSocketFrame) msg).text(); System.out.println("The message I received is:" + requestStr); // Message reply TextWebSocketFrame textWebSocketFrame = new TextWebSocketFrame("echo"); ctx.channel().writeAndFlush(textWebSocketFrame); } else { System.out.println("This is a non text message and will not be processed"); } } }
Finally, find an online WebSocket test website to see the effect
2.2 Netty built-in processing class related to websocket
In the above case, I used TextWebSocketFrame to parse text data. In fact, there are other data frame formats
name | describe |
---|---|
BinaryWebSocketFrame | WebSocketFrame data frame of binary data |
TextWebSocketFrame | WebSocketFrame data frame of text data |
CloseWebSocketFrame | The control frame represents an end request, including the end status and end reason |
ContinuationWebSocketFrame | When more than one data frame is sent, the message will be split into multiple WebSocketFrame data frames for sending. This type of data frame is dedicated to sending the remaining content. Continuation WebSocketFrame can be used to send subsequent text or binary data frames |
PingWebSocketFrame | The operation code of the control frame corresponding to the protocol message is 0x9, which is the heartbeat frame of WebSocket and sent by the server |
PongWebSocketFrame | The operation code of the control frame corresponding to the protocol message is 0xA, which is the heartbeat frame of WebSocket and sent by the client |
However, the processor on the Pipeline also has some corresponding built-in processing classes
name | describe |
---|---|
WebSocketServerProtocolHandler | Processing during protocol upgrade (handshake processing). In addition, this processor is also responsible for processing the three control frames Close\Ping\Pong of WebSocket |
WebSocketServerProtocolHandshakeHandler | Processing during protocol upgrade (handshake processing). After handshake is completed (connection establishment), this processor will trigger handshake_ The user event of complete indicates that the handshake is successful |
WebSocketFrameEncoder | Encoder, responsible for WebSocket data frame coding |
WebSocketFrameDecoder | Decoder, responsible for WebSocket data frame decoding |
Compare with the above figure to see the pipe assembly in the following figure
Forget it, see here, I just want to say... It's hard, I lost it
1
1