You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现单WebSocket服务支持多客户端连接?

核心问题修复:多客户端WebSocket失效

你的问题根源是服务端未维护全局连接池,每次新连接覆盖了旧连接的引用,导致消息只发给新客户端。修复关键:

  • 服务端必须维护所有活跃客户端的连接集合
  • 发送消息时遍历集合,广播给所有在线客户端
服务端技术选型(Python/NodeJS/PHP)

以下是三种语言的成熟方案及极简示例:

Python

推荐使用websockets异步库,性能稳定,适合高并发场景:

import asyncio
import websockets

# 存储所有活跃连接
connected_clients = set()

async def handle_client(websocket):
    connected_clients.add(websocket)
    try:
        async for message in websocket:
            # 广播消息给所有客户端
            for client in connected_clients:
                await client.send(message)
    finally:
        # 连接断开时移除
        connected_clients.remove(websocket)

start_server = websockets.serve(handle_client, "0.0.0.0", 8765)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

NodeJS

推荐ws库,轻量高效,是Node生态最常用的WebSocket库:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8765 });

const clients = new Set();

wss.on('connection', (ws) => {
  clients.add(ws);
  
  ws.on('message', (data) => {
    // 给所有在线客户端推送消息
    clients.forEach(client => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(data);
      }
    });
  });

  ws.on('close', () => clients.delete(ws));
});

PHP

推荐Ratchet库,基于ReactPHP实现异步WebSocket,适配PHP环境:
先通过Composer安装:composer require cboden/ratchet
服务端代码:

<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

class BroadcastServer implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        // 广播消息给所有客户端
        foreach ($this->clients as $client) {
            $client->send($msg);
        }
    }

    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }
}

$server = IoServer::factory(
    new HttpServer(new WsServer(new BroadcastServer())),
    8765
);

$server->run();
客户端实现(含Web Worker)

Web Worker无法直接操作DOM,必须通过消息通知主线程执行页面刷新:

主线程代码(index.html)

<!DOCTYPE html>
<html>
<body>
<script>
// 创建Web Worker
const wsWorker = new Worker('ws-worker.js');

// 监听Worker的刷新指令
wsWorker.onmessage = (e) => {
    if (e.data === 'trigger-refresh') {
        window.location.reload();
    }
};
</script>
</body>
</html>

Web Worker代码(ws-worker.js)

// 建立WebSocket连接
let ws = new WebSocket('ws://你的服务器地址:8765');

ws.onopen = () => console.log('WebSocket连接成功');

ws.onmessage = (e) => {
    // 收到服务端消息,通知主线程刷新
    if (e.data === 'refresh-page') {
        postMessage('trigger-refresh');
    }
};

// 断线自动重连
ws.onclose = () => {
    setTimeout(() => {
        ws = new WebSocket('ws://你的服务器地址:8765');
    }, 3000);
};

关键注意点

  • Web Worker无DOM操作权限,必须通过postMessage与主线程通信
  • 客户端需实现断线重连逻辑,避免连接断开后无法接收消息

内容的提问来源于stack exchange,提问作者Carlos Diaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 03:15:36