Socket.io 通过 id 断开客户端

Posted

技术标签:

【中文标题】Socket.io 通过 id 断开客户端【英文标题】:Socket.io disconnect client by id 【发布时间】:2014-08-19 05:59:48 【问题描述】:

我是 nodejs 的新手,正在尝试像很多人一样编写一个聊天室。 聊天由多个房间和客户组成。诸如 /nick /join /help /ls users /ls rooms 之类的命令可以正常工作,尽管我无法让 /kick 命令正常工作。

我只是不确定你是如何通过 id 断开客户端的,到目前为止/kick client 能够显示相应的客户端 socket.id,尽管我被困在通过 socket.id 启动的代码。

到目前为止的代码:

断开发送/kick的客户端:socket.disconnect();

从 arg /kick client 删除客户端:delete io.sockets.sockets[client];

删除客户端并不会断开它们的连接,它们仍然可以接收数据,只是不发送。

已解决

CuriousGuy 的 0.9 完美运行,对于那些感兴趣的人来说 - 这是我正在使用的代码。

服务器端:

handleClientKick(socket);

...

function handleClientKick(socket) 
  socket.on('kick', function(client) 
    if (typeof io.sockets.sockets[client] != 'undefined') 
      socket.emit('message', text: nickNames[socket.id] + ' kicked: ' + nickNames[client]);
      io.sockets.sockets[client].disconnect();
     else 
      socket.emit('message', text: 'User: ' + name + ' does not exist.');
    
  );

客户端:

kickClient = function(client) 
  this.socket.emit('kick', client);
;

【问题讨论】:

【参考方案1】:

以下代码适用于 Socket.IO 1.0,但我不确定这是否是最佳解决方案:

if (io.sockets.connected[socket.id]) 
    io.sockets.connected[socket.id].disconnect();

更新:

使用 Socket.IO 0.9,代码会略有不同:

if (io.sockets.sockets[socket.id]) 
    io.sockets.sockets[socket.id].disconnect();

【讨论】:

嗯,当我运行console.log(io.sockets.connected[socket.id]) 时,我得到一个未定义的结果? 表示要么这个socket已经断开,要么socket.id值无效。如果你运行console.log(socket.id);,你会得到什么? 我用 Socket.IO 1.0 测试了我的解决方案 socket.id 按预期工作,返回BGGkTQOOBJTcO2YukQLl 等-刚刚检查过,我使用的是 0.9.16,我会尝试使用 1.0 尝试在 1.0 上运行我的 1.0 之前的代码时遇到各种其他错误(有点预期)。我觉得奇怪的是,通过客户端 socket.id 断开客户端连接对我来说是多么困难,但通常设置 sockets.io 却如此简单。【参考方案2】:

这是一个老问题,但如果有人想知道新版本;

Socket.IO v4.X 中,io.sockets.connected[socket.id]io.sockets.sockets[socket.id] 不起作用。

所以我们需要这样做;

io.sockets.sockets.forEach((socket) => 
    // If given socket id is exist in list of all sockets, kill it
    if(socket.id === givenSocketID)
        socket.disconnect(true);
);

【讨论】:

【参考方案3】:

Socket.IO v4.X

中的替代解决方案

适用于所有套接字

const sockets = await io.fetchSockets();

对于特定的套接字

const sockets = await io.in(theSocketId).fetchSockets();

迭代套接字

for (const socket of sockets) 
     console.log("socket id",socket.id);
     socket.disconnect(true);

Reference link

【讨论】:

io.in(theSocketId).fetchSockets 会返回多个套接字吗? 不,它只会返回一个,循环可以删除【参考方案4】:

这里是另一个不需要异步语法的 Socket.IO v4 选项:

io.sockets.sockets.get(socket.id)

如果错了有人可以纠正这个,但我认为每个套接字都有一个唯一的 ID,所以应该不需要迭代。

【讨论】:

它对我不起作用,它返回 undefined 干净整洁。完美运行

以上是关于Socket.io 通过 id 断开客户端的主要内容,如果未能解决你的问题,请参考以下文章

如何检测Socket IO中的重新连接事件

socket.io 客户端在长 Node.js 函数中自动断开连接

socket.io 通过 XHR 轮询强制断开连接

使用 Socket.io 检测(客户端)连接断开

socket.io 强制断开客户端

Socket.io - 客户端断开连接后手动重新连接