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

如何通过全局io变量断开所有Socket连接?技术求助

断开所有Socket连接及多标签页非活跃用户连接的方案

一、直接断开所有Socket连接

你之前的代码错误使用了io.to().disconnect()(该方法仅用于广播,无断开连接能力),正确做法是直接遍历所有socket实例并调用其disconnect()方法:

// 遍历所有socket连接并断开
for (const [socketId, socket] of io.sockets.sockets) {
  socket.disconnect(true); // true参数表示强制断开,可跳过断开事件触发(可选)
}

如果沿用你原有的数组转换方式,修改后代码如下:

let map = io.sockets.sockets,
    array = Array.from(map, ([name, value]) => ({ name, value }));
for(let i=0;i<array.length;i++){
  array[i].value.disconnect(true); // 直接调用socket实例的disconnect方法
}

二、针对多标签页非活跃用户的断开方案

如果需求是断开同一用户的非活跃标签页连接,需要先给socket绑定用户标识(比如用户ID),再针对性处理:

1. 新连接建立时自动断开同用户旧连接

当用户在新标签页登录时,自动断开该用户其他标签页的连接:

io.on('connection', (socket) => {
  // 假设通过握手信息获取用户ID,需根据你的认证逻辑调整
  const userId = socket.handshake.auth.userId;
  
  // 让当前socket加入用户专属房间
  socket.join(`user:${userId}`);
  
  // 获取该用户的所有socket连接
  const userSockets = Array.from(io.sockets.adapter.rooms.get(`user:${userId}`).values());
  
  // 断开除当前socket外的其他同用户连接
  userSockets.forEach(sid => {
    if (sid !== socket.id) {
      const oldSocket = io.sockets.sockets.get(sid);
      oldSocket?.disconnect(true);
    }
  });
});

2. 基于超时的非活跃断开

设置超时定时器,用户长时间无操作则断开连接,同时处理多标签页冲突:

io.on('connection', (socket) => {
  const userId = socket.handshake.auth.userId;
  let timeoutTimer;

  // 重置超时定时器
  function resetTimeout() {
    clearTimeout(timeoutTimer);
    // 5分钟无操作则断开
    timeoutTimer = setTimeout(() => socket.disconnect(true), 300000);
  }

  // 用户触发任何事件时重置超时
  socket.onAny(resetTimeout);
  resetTimeout();

  // 新标签页连接时,终止旧连接的超时并断开
  socket.join(`user:${userId}`);
  const userSockets = Array.from(io.sockets.adapter.rooms.get(`user:${userId}`).values());
  userSockets.forEach(sid => {
    if (sid !== socket.id) {
      const oldSocket = io.sockets.sockets.get(sid);
      if (oldSocket) {
        clearTimeout(oldSocket.timeoutTimer);
        oldSocket.disconnect(true);
      }
    }
  });
});

核心说明:

  • io.to()仅用于向指定房间广播消息,没有断开连接的能力,必须直接操作socket实例的disconnect()方法
  • 多标签页场景下,需通过用户ID关联同一用户的所有socket连接,才能实现针对性的非活跃连接断开

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 07:27:23