socket.io分配自定义socket.id

时间:2016-03-24 18:50:22

标签: javascript node.js sockets socket.io

我会跟踪数组中连接的每个用户的列表。 因此,如果有新的连接,它将检查用户是否已经在列表中,如果他已经在列表中,然后在列表中分配他们的socket.id和相应的socket.id,否则只需添加它们列表。

用于防止同一用户在尝试多次登录时被视为2个用户。

Object.keys(client).forEach(function (key) {
    if (client[key].id == data.id){
        is_connected = true;
        socket.id = key;
    }
});

我处理尝试多次登录的用户发送/接收的消息/聊天没有问题。

socket.on('chat', function(msg){
    var data = {"name": client[socket.id].name, "message": msg};
    io.emit('chat', data);
});

聊天消息的io.emit已成功发送给尝试多次登录的用户。

我得到的问题是每当用户决定退出/断开服务器时。

io.emit('user_leave', client[socket.id].id);

[多登录案例] - >多用户和双用户是尝试多重登录的同一用户

每当主用户与服务器断开连接时,双用户都会收到' user_leave'由服务器发送,因为io.emit应该将它发送到所有套接字。

但不是这样,当子用户与服务器断开连接时,主用户不会收到' user_leave'由服务器发出。

*注意:主要用户首先登录,然后是双用户。因此,主用户信息直接保存在阵列中,而子用户socket.id则分配了主用户socket.id

[更新]

Explanation

B2 socket.id分配了B1 socket.id,io.emit for chat工作完美,而io.emit for disconnect只发送给All,除了双用户(B2)

2 个答案:

答案 0 :(得分:7)

socket.io在内部使用

socket.id作为自己的套接字列表。你无法覆盖它,或者你破坏了维护自己数据结构的能力。

您有两种选择:

  1. 您可以按原样使用现有的socket.id值(不会覆盖它),这样您就不会破坏现有行为。它已经保证在服务器上是唯一的。
  2. 您可以为自己的ID使用不同的媒体资源名称,例如socket.userId,然后您就不会发生冲突。
  3. 如果需要,您可以在自己的自定义ID和socket.io socket.id之间维护一个映射,这样您就可以从另一个中找到一个映射。

    类似的问题:Socket.io custom client ID

答案 1 :(得分:2)

io.engine对象的

generateId prop可用于设置自定义ID。

使用这种方式,可以在服务器端创建所有套接字ID而不会出现任何问题。

实际上我今天写了一篇类似问题的an answer

一个例子:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

io.engine.generateId = function (req) {
    // generate a new custom id here
    return 1
}


io.on('connection', function (socket) {

    // listing the default namespace rooms
    console.log("rooms: ", io.nsps["/"].adapter.rooms);

})

控制台输出如下:
rooms: { '/#1': Room { sockets: { '/#1': true }, length: 1 } }

似乎已经处理好了。

必须记住,套接字ID必须是不可预测的,并且考虑到安全性和应用操作的唯一价值!

额外:由于您socket.id方法的流程过于紧张,undefinedgenerateId返回,async/await组合可用于在node.js版本7.6.0及更高版本上克服了此问题。 handshake文件的node_modules/engine.io/lib/server.js方法应更改如下:

<强>前者:

Server.prototype.handshake = function (transportName, req) {
  var id = this.generateId(req);
  ...
}

新:

Server.prototype.handshake = async function (transportName, req) {
  var id = await this.generateId(req);
  ...
}