websocket无法同时建立很多连接问题

佬们,我现在想要做一个硬件监控系统,前端是微信小程序。首先使用mqtt协议将硬件与java后端通信,这步实现了。因为监控系统嘛,后端一收到硬件信息就主动推送给前端该设备的所有者。想到使用websocket实现后端主动推送信息,但是会有很多用户同时在小程序查看设备,没办法建立这么多websocket连接怎么办呢

  • 这篇博客: 【开源物联网】基于WebSocket进行MQTT通信中的 2.2建立WebSocket连接 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 以微信小程序作为客户端,建立与服务端简的WebSocket连接,客户端操作详情请参考微信小程序MQTT通信及开源框架实现,本文关注基于WebSocket进行MQTT的流程。

    建立WebSocket连接由两个步骤完成:

    •  客户端首先通过http协议发送一条协议升级(升级到websocket)请求报文;
    • 服务端进行握手成功后返回一条101 http协议报文表示WebSocket连接已建立。

    其代码实现如下:

    /**
    	 * 唯一的一次http请求,用于创建websocket
    	 */
    	private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
    		// 要求Upgrade为websocket,过滤掉get/Post
    		if (!req.decoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) {
    			// 若不是websocket方式,则创建BAD_REQUEST的req,返回给客户端
    			sendHttpResponse(ctx, req,
    					new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
    			return;
    		}
    		logger.info(req.content());
    		// ctx.fireChannelRead(req.content());
    		WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
    				"ws://localhost:1885/websocket",
    				"mqtt", false);
    		handshaker = wsFactory.newHandshaker(req);
    		if (handshaker == null) {
    			WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
    		} else {
    			req.headers().set("Sec-WebSocket-Protocol", "mqtt");
    			handshaker.handshake(ctx.channel(), req);
    		}
    	}

     识别出收到的报文是Http报文时在第22行进行握手完成协议升级成websocket协议建立连接。

    建立连接过程跟踪

    采用wireshark工具对连接过程进行跟踪可以看到如下报文信息:

    WebSocket连接建立报文跟踪 

    从服务器端返回的101报文表示建立连接成功。

  • 以下回答由chatgpt基于相关博客总结生成:

    可以考虑使用WebSocket的广播机制来优化这个问题,避免建立多个WebSocket连接。具体实现方法如下:

    1.在后端建立一个WebSocket连接,并且保存下来。 2.使用一个数据结构来保存所有需要推送的消息,这个数据结构可以使用队列、堆栈等等,根据实际需求选择。 3.当有需要推送的消息时,将消息加入数据结构中。 4.使用WebSocket的广播机制,将数据结构中的消息发送给所有客户端; 5.客户端收到消息后,将其展示在界面上。

    具体的实现细节可以参考以下代码示例:

    后端代码示例:

    // 建立WebSocket连接 private void initWebSocket() { // 创建一个WebSocketServerHandshakerFactory对象 WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( "ws://localhost:8888/websocket", null, false);

    // 通过WebSocketServerHandshakerFactory对象创建一个WebSocketServerHandshaker对象
    handshaker = wsFactory.newHandshaker(request);
    if (handshaker == null) {
        WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
    } else {
        // 向客户端发送握手消息
        ChannelFuture future = handshaker.handshake(ctx.channel(), request);
        if (future.isSuccess()) {
            // WebSocket连接建立成功
    
            // 将当前连接保存到ChannelGroup中
            channelGroup.add(ctx.channel());
        }
    }
    

    }

    // 推送消息给所有客户端 private void sendMessageToAllClients(Message message) { // 将消息加入消息队列中 messageQueue.offer(message);

    // 广播消息给所有客户端
    for (Channel ch : channelGroup) {
        if (ch.isActive()) {
            ch.writeAndFlush(new TextWebSocketFrame("push:" + message.getContent()));
        }
    }
    

    }

    // 接收客户端发送的消息 @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { if ("heartbeat".equals(msg.text())) { // 心跳消息,不做处理 return; }

    // 将客户端发送的消息转换成Message对象,并且推送给所有客户端
    Message message = convertToMessage(msg.text());
    sendMessageToAllClients(message);
    

    }

    前端代码示例:

    // 建立WebSocket连接 var ws = new WebSocket("ws://localhost:8888/websocket");

    // 监听WebSocket连接 ws.onopen = function() { console.log("WebSocket连接已建立"); };

    // 监听WebSocket消息 ws.onmessage = function(event) { console.log("接收到消息:" + event.data); };

    // 向服务器发送消息 ws.send("hello");

    以上代码示例仅供参考,具体实现细节需要根据实际需求进行相应的修改和调整。

你的思路是没有问题的,可以使用websocket 作为消息通知组件。你说的用户太多没办法建立太多websocket连接。按道理websocket的底层协议TCP 是没有连接数限制的,所以不用担心这个。通常WebSocket可以支持成千上万的连接。
你先把服务搞出来,做个简单的压测,看下具体承载量。如果达不到预期,要么堆硬件使用多个WebSocket服务器进行负载均衡。要么可以通过调整服务器的线程池大小、网络缓冲区大小、连接超时时间等参数,来优化服务器的性能和连接数。不要一上来担心技术上的问题,你需要做的是把你的程序优化好,至少在你的应用层保证心跳检测、断线重连、连接池等功能的实现。有那么大的用户量,就应该有那么大的基础设施的投入。