在断开连接事件中获取客户端当前所在的房间列表

Posted

技术标签:

【中文标题】在断开连接事件中获取客户端当前所在的房间列表【英文标题】:Get the list of rooms the client is currently in on disconnect event 【发布时间】:2014-11-07 22:32:04 【问题描述】:

我正在尝试查找客户端当前在断开连接事件(关闭浏览器/重新加载页面/互联网连接已断开)时所在的房间列表。

我需要它的原因如下:用户进入了几个房间。然后其他人也做了同样的事情。然后他关闭浏览器选项卡。我想通知他所在房间里的所有人他离开了。

所以我需要在 on 'disconnect' 事件中做点什么。

io.sockets.on('connection', function(client)
  ...
  client.on('disconnect', function()

  );
);

我已经尝试了两种方法,发现都是错误的:

1) 遍历adapter.rooms

for (room in client.adapter.rooms)
   io.sockets.in(room).emit('userDisconnected', UID);
 

这是错误的,因为适配器房间包含所有房间。不仅是我的客户所在的房间。

2) 通过client.rooms。这将返回客户端所在房间的正确列表,但在断开连接事件时不返回。断开连接时,此列表已为空 []

那我该怎么做呢?在撰写本文时,我正在使用最新的 socket.io:1.1.0

【问题讨论】:

【参考方案1】:

默认情况下这是不可能的。看看socket.io的源码。

你有 Socket.prototype.onclose 方法,它在 socket.on('disconnect',..) 回调之前执行。所以在那之前所有的房间都被留下了。

/**
 * Called upon closing. Called by `Client`.
 *
 * @param String reason
 * @api private
 */

Socket.prototype.onclose = function(reason)
  if (!this.connected) return this;
  debug('closing socket - reason %s', reason);
  this.leaveAll();
  this.nsp.remove(this);
  this.client.remove(this);
  this.connected = false;
  this.disconnected = true;
  delete this.nsp.connected[this.id];
  this.emit('disconnect', reason);
;

解决方案可能是破解 socket.js 库代码或覆盖此方法然后调用原始方法。我很快对其进行了测试,似乎可以正常工作:

socket.onclose = function(reason)
    //emit to rooms here
    //acceess socket.adapter.sids[socket.id] to get all rooms for the socket
    console.log(socket.adapter.sids[socket.id]);
    Object.getPrototypeOf(this).onclose.call(this,reason);

【讨论】:

1.3.6 仍然如此 :( @DerM 不错的解决方案!但是socket.adapter.sids [socket.id] 不起作用,是的socket.rooms 得到所有房间的插座!【参考方案2】:

我知道,这是一个老问题,但在当前版本的 socket.io 中,有一个在断开连接之前运行的事件,您可以访问他加入的房间列表。

client.on('disconnecting', function()
    Object.keys(socket.rooms).forEach(function(roomName)
        console.log("Do something to room");
    );
);

https://github.com/socketio/socket.io/issues/1814

另见:

Server API documentation - 'disconnecting' event

【讨论】:

以上是关于在断开连接事件中获取客户端当前所在的房间列表的主要内容,如果未能解决你的问题,请参考以下文章

Javascript Websockets在页面卸载时断开连接

如何在socket.io中的断开事件上获取断开连接的客户端的套接字ID

MySQL笔记-查询进程列表(查客户端IP使用的用户当前状态ID号使用的库)及断开客户端连接

Ktor sse 客户端断开连接

Socket.io 不会在断开连接时向房间发送消息

角度 SignalR 经常断开连接并显示错误状态代码 1006