当前位置:首页 > CN2资讯 > 正文内容

windows下搭建java mqtt服务器

2天前CN2资讯


在上一篇中我们对WebSocket协议进行了介绍,在开始之前,我们还是先看下Netty的整体组件图:

从上图中可以看出Netty支持的协议包括:HTTP&WebSocket,Google Protobuf等协议。

本篇我们就基于Netty来搭建WebSocket服务的完整案例来实现消息的主动推送功能,并在其中贯穿一下上一篇中的WebSocket的部分理论知识!

一、案例实现

2.1 服务端定义

服务端的定义和之前的案例没啥差别(绑定主线程和工作线程),这里为了能够更全面的查看到相关请求的日志信息,就把日志级别调整成了Debug级别,其他的都类似,具体代码实现如下:

package com.rain.interview.netty.netty10;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;import io.netty.handler.codec.http.HttpObjectAggregator;import io.netty.handler.codec.http.HttpServerCodec;import io.netty.handler.codec.protobuf.ProtobufDecoder;import io.netty.handler.codec.protobuf.ProtobufEncoder;import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;import io.netty.handler.stream.ChunkedWriteHandler;/** * <pre>功能描述:</br>Netty基于WebSocket协议栈开发<pre> * @ProjectName prepareInterview * @Author rain * @date 2019-10-16 22:36 * @version v1.0 */public class WebSocketServer { /** * <pre>服务端绑定逻辑</pre> * * @param port 端口号 * @throws InterruptedException */ public void bind(int port) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.DEBUG)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline() .addLast("Logging Handler",new LoggingHandler(LogLevel.DEBUG)) .addLast("Http Codec",new HttpServerCodec()) .addLast("Http Aggregator",new HttpObjectAggregator(65535)) .addLast("Http Chunked",new ChunkedWriteHandler()) .addLast("Socket Server",new WebSocketServerHandler()); } }); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws InterruptedException { int port = 8080; if (args != null && args.length > 0) { try { port = Integer.valueOf(args[0]); } catch (NumberFormatException e) { } } new WebSocketServer().bind(port); }}

2.2 消息处理

【代码解读】

由于建立websocket连接的时候,第一次使用的还是http协议,然后判断头部信息中包含Upgrade: websocket就会进行协议升级,通过WebSocketServerHandshakerFactory创建socket对象并通过handshaker握手建立连接,后续的请求再次进来就可以直接使用第一次创建好的通道,在handlerWebSocketFrame中对websocket消息进行处理,这里针对客户端的几种行为做了判断,比如:关闭请求,Ping请求,消息类型判断(这里暂时支持文本类型的消息)。

具体的代码如下所示:

package com.rain.interview.netty.netty10;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.DefaultFullHttpResponse;import io.netty.handler.codec.http.FullHttpRequest;import io.netty.handler.codec.http.HttpResponseStatus;import io.netty.handler.codec.http.HttpVersion;import io.netty.handler.codec.http.websocketx.*;import io.netty.util.CharsetUtil;import java.util.Date;import static io.netty.handler.codec.http.HttpUtil.isKeepAlive;import static io.netty.handler.codec.http.HttpUtil.setContentLength;/** * <pre>功能描述:</br>WebSocket处理器<pre> * @ProjectName prepareInterview * @Author rain * @date 2019-10-16 22:39 * @version v1.0 */public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> { private WebSocketServerHandshaker handshaker; @Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("收到消息:"+msg); /** 传统http接入 **/ if (msg instanceof FullHttpRequest) { System.out.println("==========FullHttpRequest Processed ! ============="); handleHttpRequest(ctx, (FullHttpRequest) msg); } /** websocket接入 **/ else if (msg instanceof WebSocketFrame) { System.out.println("==========WebSocketFrame Processed ! ============="); handleWebSocketFrame(ctx, (WebSocketFrame) msg); } } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } /** * <pre>WebSocket处理</pre> * * @param ctx 上下文 * @param frame websocket */ private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) { /** 断开连接处理 **/ if (frame instanceof CloseWebSocketFrame) { handshaker.close(ctx.channel(), ((CloseWebSocketFrame) frame).retain()); return; } /** ping处理 **/ if (frame instanceof PingWebSocketFrame) { ctx.channel().write(new PongWebSocketFrame(frame.content().retain())); return; } /** 非文本不支持 **/ if (!(frame instanceof TextWebSocketFrame)) { throw new UnsupportedOperationException(String.format("%s frame types not supported !", frame.getClass().getName())); } /** 对文本信息处理,并响应客户端 **/ String reqMsg = ((TextWebSocketFrame) frame).text(); System.out.println(String.format("%s received %s ", ctx.channel(), reqMsg)); ctx.channel().write(new TextWebSocketFrame(reqMsg + ",欢迎使用Netty WebSocket 服务,现在时间是:" + new Date().toString())); } /** * <pre>普通HTTP处理</pre> * * @param ctx 上下文 * @param req */ private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { /** 1.判断解码是否正常并且判断Upgrade是否为websocket **/ if (!req.decoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); return; } WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( "ws://localhost:8080/websocket", null, false ); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { /** 版本不支持 **/ WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { /** 握手建立连接 **/ handshaker.handshake(ctx.channel(), req); } } /** * <pre>发送响应</pre> * * @param ctx 上下文 * @param req 请求 * @param resp 响应 */ private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, DefaultFullHttpResponse resp) { if (resp.status().code() != 200) { ByteBuf buf = Unpooled.copiedBuffer(resp.status().toString(), CharsetUtil.UTF_8); resp.content().writeBytes(buf); buf.release(); setContentLength(resp, resp.content().readableBytes()); } ChannelFuture f = ctx.channel().writeAndFlush(resp); if (!isKeepAlive(req) || resp.status().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } }}

2.3 客户端

[1].初始化客户端

const ws = new WebSocket("ws://localhost:8888/websocket");ws.onmessage=function(event){ let message = { name:'Server', content: event.data } console.info(JSON.stringify(message));}ws.onopen = function(){ let message = { name:'Server', content: '连接成功!' } console.info(JSON.stringify(message));}ws.onclose = function(){ let message = { name:'Server', content: '已断开' } console.info(JSON.stringify(message));}ws.onerror = function(){ let message = { name:'Server', content: '连接错误' } console.info(JSON.stringify(message));}

[2].发送消息

ws.send(JSON.stringify({userId:1,content:'I\'m User One'}));

二、结果分析

[1].服务端响应

[1.1]建立连接

14:48:55.077 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9624fea3, L:/0:0:0:0:0:0:0:0:8888] READ: [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829]14:48:55.078 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0x9624fea3, L:/0:0:0:0:0:0:0:0:8888] READ COMPLETE14:48:55.079 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] REGISTERED14:48:55.079 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] ACTIVE客户端加入连接:[id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829]14:48:55.081 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] READ: 616B +-------------------------------------------------+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f |+--------+-------------------------------------------------+----------------+|00000000| 47 45 54 20 2f 77 65 62 73 6f 63 6b 65 74 20 48 |GET /websocket H||00000010| 54 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 6c |TTP/1.1..Host: l||00000020| 6f 63 61 6c 68 6f 73 74 3a 38 38 38 38 0d 0a 43 |ocalhost:8888..C||00000030| 6f 6e 6e 65 63 74 69 6f 6e 3a 20 55 70 67 72 61 |onnection: Upgra||00000040| 64 65 0d 0a 50 72 61 67 6d 61 3a 20 6e 6f 2d 63 |de..Pragma: no-c||00000050| 61 63 68 65 0d 0a 43 61 63 68 65 2d 43 6f 6e 74 |ache..Cache-Cont||00000060| 72 6f 6c 3a 20 6e 6f 2d 63 61 63 68 65 0d 0a 55 |rol: no-cache..U||00000070| 73 65 72 2d 41 67 65 6e 74 3a 20 4d 6f 7a 69 6c |ser-Agent: Mozil||00000080| 6c 61 2f 35 2e 30 20 28 57 69 6e 64 6f 77 73 20 |la/5.0 (Windows ||00000090| 4e 54 20 31 30 2e 30 3b 20 57 69 6e 36 34 3b 20 |NT 10.0; Win64; ||000000a0| 78 36 34 29 20 41 70 70 6c 65 57 65 62 4b 69 74 |x64) AppleWebKit||000000b0| 2f 35 33 37 2e 33 36 20 28 4b 48 54 4d 4c 2c 20 |/537.36 (KHTML, ||000000c0| 6c 69 6b 65 20 47 65 63 6b 6f 29 20 43 68 72 6f |like Gecko) Chro||000000d0| 6d 65 2f 37 32 2e 30 2e 33 36 32 36 2e 31 30 39 |me/72.0.3626.109||000000e0| 20 53 61 66 61 72 69 2f 35 33 37 2e 33 36 0d 0a | Safari/537.36..||000000f0| 55 70 67 72 61 64 65 3a 20 77 65 62 73 6f 63 6b |Upgrade: websock||00000100| 65 74 0d 0a 4f 72 69 67 69 6e 3a 20 68 74 74 70 |et..Origin: http||00000110| 73 3a 2f 2f 31 30 2e 30 2e 31 34 31 2e 31 31 30 |s://10.0.141.110||00000120| 3a 38 34 34 33 0d 0a 53 65 63 2d 57 65 62 53 6f |:8443..Sec-WebSo||00000130| 63 6b 65 74 2d 56 65 72 73 69 6f 6e 3a 20 31 33 |cket-Version: 13||00000140| 0d 0a 41 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e |..Accept-Encodin||00000150| 67 3a 20 67 7a 69 70 2c 20 64 65 66 6c 61 74 65 |g: gzip, deflate||00000160| 2c 20 62 72 0d 0a 41 63 63 65 70 74 2d 4c 61 6e |, br..Accept-Lan||00000170| 67 75 61 67 65 3a 20 7a 68 2d 43 4e 2c 7a 68 3b |guage: zh-CN,zh;||00000180| 71 3d 30 2e 39 2c 65 6e 3b 71 3d 30 2e 38 0d 0a |q=0.9,en;q=0.8..||00000190| 43 6f 6f 6b 69 65 3a 20 54 59 5f 53 45 53 53 49 |Cookie: TY_SESSI||000001a0| 4f 4e 5f 49 44 3d 35 32 62 37 66 62 61 64 2d 66 |ON_ID=52b7fbad-f||000001b0| 63 31 34 2d 34 37 33 33 2d 38 61 39 33 2d 37 36 |c14-4733-8a93-76||000001c0| 63 36 34 36 65 62 38 33 61 31 3b 20 6c 63 63 5f |c646eb83a1; lcc_||000001d0| 73 65 6c 65 63 74 65 64 5f 72 65 67 69 6f 6e 3d |selected_region=||000001e0| 25 32 32 63 6e 2d 68 61 6e 67 7a 68 6f 75 25 32 |%22cn-hangzhou%2||000001f0| 32 0d 0a 53 65 63 2d 57 65 62 53 6f 63 6b 65 74 |2..Sec-WebSocket||00000200| 2d 4b 65 79 3a 20 42 36 37 46 77 36 78 38 71 39 |-Key: B67Fw6x8q9||00000210| 6c 56 46 6d 73 5a 79 64 73 34 48 77 3d 3d 0d 0a |lVFmsZyds4Hw==..||00000220| 53 65 63 2d 57 65 62 53 6f 63 6b 65 74 2d 45 78 |Sec-WebSocket-Ex||00000230| 74 65 6e 73 69 6f 6e 73 3a 20 70 65 72 6d 65 73 |tensions: permes||00000240| 73 61 67 65 2d 64 65 66 6c 61 74 65 3b 20 63 6c |sage-deflate; cl||00000250| 69 65 6e 74 5f 6d 61 78 5f 77 69 6e 64 6f 77 5f |ient_max_window_||00000260| 62 69 74 73 0d 0a 0d 0a |bits.... |+--------+-------------------------------------------------+----------------+Receive Msg: HttpObjectAggregator$AggregatedFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: CompositeByteBuf(ridx: 0, widx: 0, cap: 0, components=0))GET /websocket HTTP/1.1Host: localhost:8888Connection: UpgradePragma: no-cacheCache-Control: no-cacheUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36Upgrade: websocketOrigin: https://10.0.141.110:8443Sec-WebSocket-Version: 13Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8Cookie: TY_SESSION_ID=52b7fbad-fc14-4733-8a93-76c646eb83a1; lcc_selected_region=%22cn-hangzhou%22Sec-WebSocket-Key: B67Fw6x8q9lVFmsZyds4Hw==Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bitscontent-length: 0FullHttpRequest Process !14:48:55.082 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] WebSocket version V13 server handshake14:48:55.082 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker - WebSocket version 13 server handshake key: B67Fw6x8q9lVFmsZyds4Hw==, response: X60lyL8CoxqX2HkEL9wVBnHWikc=14:48:55.083 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] WRITE: 129B +-------------------------------------------------+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f |+--------+-------------------------------------------------+----------------+|00000000| 48 54 54 50 2f 31 2e 31 20 31 30 31 20 53 77 69 |HTTP/1.1 101 Swi||00000010| 74 63 68 69 6e 67 20 50 72 6f 74 6f 63 6f 6c 73 |tching Protocols||00000020| 0d 0a 75 70 67 72 61 64 65 3a 20 77 65 62 73 6f |..upgrade: webso||00000030| 63 6b 65 74 0d 0a 63 6f 6e 6e 65 63 74 69 6f 6e |cket..connection||00000040| 3a 20 75 70 67 72 61 64 65 0d 0a 73 65 63 2d 77 |: upgrade..sec-w||00000050| 65 62 73 6f 63 6b 65 74 2d 61 63 63 65 70 74 3a |ebsocket-accept:||00000060| 20 58 36 30 6c 79 4c 38 43 6f 78 71 58 32 48 6b | X60lyL8CoxqX2Hk||00000070| 45 4c 39 77 56 42 6e 48 57 69 6b 63 3d 0d 0a 0d |EL9wVBnHWikc=...||00000080| 0a |. |+--------+-------------------------------------------------+----------------+14:48:55.083 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] FLUSH14:48:55.083 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] READ COMPLETE14:48:55.084 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] FLUSH

[1.2].发送数据

14:49:33.057 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] READ: 57B +-------------------------------------------------+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f |+--------+-------------------------------------------------+----------------+|00000000| 81 b3 e3 c4 d2 12 98 e6 a7 61 86 b6 9b 76 c1 fe |.........a...v..||00000010| f0 73 93 ab be 7e 8c e6 fe 30 80 ac b3 66 a0 ab |.s...~...0...f..||00000020| bc 66 86 aa a6 30 d9 e6 9a 77 8f a8 bd 32 b4 a1 |.f...0...w...2..||00000030| b0 61 8c a7 b9 77 97 e6 af |.a...w... |+--------+-------------------------------------------------+----------------+14:49:33.059 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame opCode=114:49:33.059 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder - Decoding WebSocket Frame length=51Receive Msg: TextWebSocketFrame(data: PooledUnsafeDirectByteBuf(ridx: 0, widx: 51, cap: 51))WebSocketFrame Process ![id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] received {"userId":"apollo","chatContent":"Hello Websocket"} 14:49:33.072 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] READ COMPLETE14:49:33.072 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.codec.http.websocketx.WebSocket08FrameEncoder - Encoding WebSocket Frame opCode=1 length=13514:49:33.073 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] WRITE: 139B +-------------------------------------------------+ | 0 1 2 3 4 5 6 7 8 9 a b c d e f |+--------+-------------------------------------------------+----------------+|00000000| 81 7e 00 87 7b 22 75 73 65 72 49 64 22 3a 22 61 |.~..{"userId":"a||00000010| 70 6f 6c 6c 6f 22 2c 22 63 68 61 74 43 6f 6e 74 |pollo","chatCont||00000020| 65 6e 74 22 3a 22 48 65 6c 6c 6f 20 57 65 62 73 |ent":"Hello Webs||00000030| 6f 63 6b 65 74 22 7d 2c e6 ac a2 e8 bf 8e e4 bd |ocket"},........||00000040| bf e7 94 a8 4e 65 74 74 79 20 57 65 62 53 6f 63 |....Netty WebSoc||00000050| 6b 65 74 20 e6 9c 8d e5 8a a1 ef bc 8c e7 8e b0 |ket ............||00000060| e5 9c a8 e6 97 b6 e9 97 b4 e6 98 af ef bc 9a 46 |...............F||00000070| 72 69 20 4f 63 74 20 31 38 20 31 34 3a 34 39 3a |ri Oct 18 14:49:||00000080| 33 33 20 43 53 54 20 32 30 31 39 |33 CST 2019 |+--------+-------------------------------------------------+----------------+14:49:33.073 [nioEventLoopGroup-3-2] DEBUG io.netty.handler.logging.LoggingHandler - [id: 0xaa3444b2, L:/0:0:0:0:0:0:0:1:8888 - R:/0:0:0:0:0:0:0:1:64829] FLUSH

[2].客户端响应

[2.1].请求头和响应头

HTTP/1.1 101 Switching Protocolsupgrade: websocketconnection: upgradesec-websocket-accept: k0IsewHFp5y6ITP+etLhMQe2hKs=GET ws://localhost:8888/websocket HTTP/1.1Host: localhost:8888Connection: UpgradePragma: no-cacheCache-Control: no-cacheUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36Upgrade: websocketOrigin: https://10.0.141.110Sec-WebSocket-Version: 13Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8Sec-WebSocket-Key: 2NynAl+9iLGheRtvskTC2Q==Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

[2.2].客户端响应结果

"{\"userId\":1,\"content\":\"I'm User One\"},欢迎使用Netty WebSocket 服务,现在时间是:Fri Oct 18 14:56:37 CST 2019"

三、总结

本篇文章,结合Netty搭建了一个简单的WebSocket服务,并且通过浏览器来模拟客户端的连接和请求。上一篇中搭建的WebSocket服务是通过使用SpringBoot+WebSocket实现的,它依赖于tomcat服务运行,虽然看起来也比较简单,但是通过本篇使用Netty来搭建,发现简化了好多,只需要200-300行代码就可以搞定了。看样子,Netty还是非常强大的哈!HTTP协议和WebSocket协议都属于应用层的协议,从下一篇开始,我们将讲讲Netty基于UDP、TCP协议的应用,敬请期待~

    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/30659.html

    分享给朋友:

    “windows下搭建java mqtt服务器” 的相关文章

    线路板上的CN2是什么意思?详细接线指南

    在线路板(PCB)设计中,标识符CN2是一个常见的术语,但它对新手来说可能有些模糊。CN2到底是什么意思?它在电路板中扮演什么角色?如何正确接线?本文将逐步为您解答这些问题,帮助您更好地理解线路板上的标识符以及接线方法。CN2的含义在电子工程中,CN通常代表“Connector”,即“连接器”。根据...

    最便宜的域名注册平台推荐与选择技巧

    在创建一个新网站时,域名是一个不可或缺的部分。众所周知,一个好的域名能够提升品牌形象,也让用户更容易记住。选择便宜的域名注册平台,可以让我们在网站建设的开销上更加省钱。这里有几个我认为特别值得关注的平台,可能会对你有帮助。 1.1 NameCheap的优势与价格分析 让我先谈谈NameCheap。说...

    腾讯云国际站:助力企业全球化发展的云计算服务平台

    腾讯云国际站是腾讯云为全球用户打造的云计算服务平台,其目的是为企业和开发者提供强大的技术支持。这一平台的核心特点在于其全球化的服务网络与数据中心布局,让每位用户都能感受到来自不同地区的高效服务。 全球服务与数据中心特点 我对腾讯云国际站的全球服务网络感到非常惊艳。它在全球开通了21个地理区域,涵盖了...

    搬瓦工最新优惠码分享,让你享受更多折扣

    在寻找优质VPS时,搬瓦工(BandwagonHost)绝对是一个热门的选择。为了让用户在购买过程中享受到更多优惠,现在分享一下搬瓦工最新的优惠码。 最新优惠码是BWHCGLUKKB,通过这个优惠码用户可以享受6.78%的循环优惠,这一优惠适用于搬瓦工全场的商品,无论是新购、续费还是升级服务,都能获...

    如何查看域名是否被墙:检测工具与方法指南

    域名被墙是一个对很多网站管理员和用户来说都比较陌生的概念。简单来说,当一个网站的内容被认为敏感或者违反某些规定时,防火墙就会把这个域名屏蔽。即使用户通过输入域名试图访问,DNS 解析也许正常,但实际上网站却无法顺利加载。在国内用户访问国外网站或者国外用户尝试访问国内网站时,情况尤为明显,就好像在国际...

    国内注册ChatGPT的安全与实用指南

    在使用ChatGPT服务时,安全与隐私保护是非常重要的。首先,我总是尽量避免在聊天或任何交流中输入敏感信息。无论是个人身份、财务信息,还是其他隐私内容,我都保持警惕,确保我的信息不会被泄露。即便是在与AI进行对话时,这种谨慎也同样必要,因为即使是最可信的平台也无法完全保障信息不被滥用。 还有一点是选...