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

如何实现禁止同一浏览器标签页建立多个WebSocket连接?

实现单客户端独占WebSocket连接的方案

后端(javax.websocket)实现

核心思路是维护一个活跃连接计数器,在新连接建立时检查当前连接数,若已存在活跃连接则直接关闭新连接。

代码示例

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/card-game")
public class CardGameWebSocket {
    // 原子计数器,保证多线程下的线程安全
    private static final AtomicInteger activeConnections = new AtomicInteger(0);

    @OnOpen
    public void onOpen(Session session) {
        // 尝试递增计数器,若递增后大于1,说明已有活跃连接
        if (activeConnections.incrementAndGet() > 1) {
            try {
                // 发送关闭原因并关闭新连接
                session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "已有玩家连接,请稍后再试"));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 计数器回退,因为这个连接没有成功建立
                activeConnections.decrementAndGet();
            }
        } else {
            // 连接成功,可初始化游戏逻辑
            System.out.println("玩家已连接,会话ID: " + session.getId());
        }
    }

    @OnClose
    public void onClose(Session session) {
        // 连接关闭时递减计数器
        activeConnections.decrementAndGet();
        System.out.println("玩家已断开,会话ID: " + session.getId());
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        // 发生错误时也要确保计数器正确(避免异常导致计数不一致)
        activeConnections.decrementAndGet();
        throwable.printStackTrace();
    }
}

关键细节

  • 使用AtomicInteger而非普通int:WebSocket的连接事件是多线程触发的,原子类能保证计数操作的线程安全,避免并发下的计数错误。
  • 关闭连接时指定关闭码和原因:前端可以通过这些信息给用户明确的提示,提升体验。
  • 错误处理中同步计数器:防止连接异常断开时计数器未更新,导致后续无法正常建立连接。

前端(JavaScript)实现

前端需要监听WebSocket的关闭事件,根据后端返回的关闭原因提示用户。

代码示例

const ws = new WebSocket('ws://localhost:8080/card-game');

ws.onopen = function() {
    console.log('连接成功,开始游戏');
    // 这里可以初始化游戏界面
};

ws.onclose = function(event) {
    if (event.code === 1008 && event.reason === '已有玩家连接,请稍后再试') {
        alert('当前已有玩家在游戏中,请稍后再尝试连接!');
    } else {
        console.log('连接关闭,原因: ' + event.reason);
    }
};

ws.onerror = function(error) {
    console.error('连接出错: ', error);
};

额外优化

  • 可以在前端添加重连限制:比如用户看到提示后,避免频繁自动重连,减少后端压力。
  • 连接失败后提供重试按钮,让用户手动触发重连。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:35:29