socket.io分配自定义socket.id

Lck*_*day 6 javascript sockets node.js 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;
    }
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

io.emit('user_leave', client[socket.id].id);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

[更新]

说明

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

jfr*_*d00 7

socket.idsocket.io在内部使用它自己的套接字列表.您不能覆盖它,或者您破坏了维护自己的数据结构的能力.

你有两个选择:

  1. 您可以socket.id按原样使用现有值(不覆盖它),因此您不会破坏现有行为.它已经保证在服务器上是唯一的.
  2. 您可以为自己的ID使用不同的属性名称socket.userId,然后您就不会发生冲突.

如果需要,您可以在自己的自定义ID和socket.io之间维护一个映射,socket.id这样您就可以从另一个中获取一个映射.

类似的问题:Socket.io自定义客户端ID


efk*_*kan 7

io.engine对象的generateId道具可用于设置自定义 id。

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

其实我今天写一个类似问题的答案

一个例子:

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);

})
Run Code Online (Sandbox Code Playgroud)

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

好像已经处理好了。

必须记住,考虑到安全性和应用程序操作,socket id 必须是不可预测的和唯一的值!

额外:如果由于您对方法的密集处理socket.id而返回,则可以使用组合来解决7.6.0 及更高版本的此问题。文件的方法应更改如下:undefinedgenerateIdasync/awaitnode.js
handshakenode_modules/engine.io/lib/server.js

以前的:

Server.prototype.handshake = function (transportName, req) {
  var id = this.generateId(req);
  ...
}
Run Code Online (Sandbox Code Playgroud)

新的:

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