Socket.io自定义客户端ID

pme*_*ino 29 javascript node.js socket.io

我正在使用socket.io创建一个聊天应用程序,我想使用我的自定义客户端ID,而不是默认的(8411473621394412707,1120516437992682114).在连接或仅使用某些内容跟踪每个ID的自定义名称时,是否有任何方法可以发送自定义标识符?谢谢!

osc*_*arm 43

您可以在服务器上创建一个数组,并在其上存储自定义对象.例如,您可以将Socket.io创建的ID和每个客户端发送的自定义ID存储到服务器:

var util = require("util"),
    io = require('/socket.io').listen(8080),
    fs = require('fs'),
    os = require('os'),
    url = require('url');

    var clients =[];

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

        socket.on('storeClientInfo', function (data) {

            var clientInfo = new Object();
            clientInfo.customId         = data.customId;
            clientInfo.clientId     = socket.id;
            clients.push(clientInfo);
        });

        socket.on('disconnect', function (data) {

            for( var i=0, len=clients.length; i<len; ++i ){
                var c = clients[i];

                if(c.clientId == socket.id){
                    clients.splice(i,1);
                    break;
                }
            }

        });
    });
Run Code Online (Sandbox Code Playgroud)

在此示例中,您需要从每个客户端调用storeClientInfo.

<script>
    var socket = io.connect('http://localhost', {port: 8080});

    socket.on('connect', function (data) {
        socket.emit('storeClientInfo', { customId:"000CustomIdHere0000" });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 我建议使用Redis而不是变量。它将提供更好的可伸缩性,并且如果服务器由于错误而崩溃,也不会丢失数据。 (2认同)

efk*_*kan 13

要设置自定义套接字ID,必须覆盖generateId函数.服务器对象的两个eioengine道具都可用于管理此操作.Socket.io

一个简单的例子:

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) {
    console.log(socket.id); // writes 1 on the console
})
Run Code Online (Sandbox Code Playgroud)

它似乎已被处理.

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

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

当前:

// engine.io/lib/server.js

Server.prototype.generateId = function (req) {
  return base64id.generateId();
};

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

新:

// function assignment

io.engine.generateId = function (req) {
  return new Promise(function (resolve, reject) {
    let id;
    // some intense id generation processes
    // ...
    resolve(id);
  });
};


// engine.io/lib/server.js

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

注意:Engine.io v4.0中,generateId方法将接受回调.所以它不需要改变handshake方法.只有generateId方法替换就足够了.例如:

io.engine.generateId = function (req, callback) {
  // some intense id generation processes
  // ...
  callback(id);
};
Run Code Online (Sandbox Code Playgroud)

  • 为什么这个 ID 不可预测很重要?客户端可以在连接时指定自己的 ID 吗?如果不是,我不明白为什么这是必要的 (2认同)

Sal*_*ali 6

在最新的socket.io(版本1.x)中,您可以执行类似的操作

socket  = io.connect('http://localhost');

socket.on('connect', function() {
    console.log(socket.io.engine.id);     // old ID
    socket.io.engine.id = 'new ID';
    console.log(socket.io.engine.id);     // new ID
});
Run Code Online (Sandbox Code Playgroud)


Roh*_*had 6

这适用于2.2.0 及以上版本的 Socket.IO

要设置自定义 Socket Id,generateId必须覆盖函数。

一个简单的例子:

服务器端

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

io.use((socket, next) => {
  io.engine.generateId = () => {
    // USE ONE OF THESE
    socket.handshake.query.CustomId; // this work for me
    // return socket.handshake.query.CustomId;
  }
  next(null, true);
});

io.on('connection', function (socket) {
    console.log(socket.id);
})
Run Code Online (Sandbox Code Playgroud)

克林特·赛德

io.connect(URL, { query: "CustomId = CUSTOM ID IS HERE" })
Run Code Online (Sandbox Code Playgroud)

注意:请记住,套接字 ID 必须是唯一值。


Jam*_*ate 5

我会使用一个对象作为哈希查找 - 这将节省您通过数组循环

var clients = {};
clients[customId] = clientId;

var lookup = clients[customId];
Run Code Online (Sandbox Code Playgroud)


小智 5

不要将套接字ID更改为您自己选择的ID,这会完全破坏Socket.io房间系统。它会静默失败,并且您不知道为什么您的客户端没有收到消息。


小智 5

为什么不是一个更简单的解决方案,不需要维护连接的客户端数组,并且不覆盖内部套接字 ID?

io.on("connection", (socket) => {
    socket.on('storeClientInfo', (data) => {
        console.log("connected custom id:", data.customId);
        socket.customId = data.customId;
    });

    socket.on("disconnect", () => {
        console.log("disconnected custom id:", socket.customId);
    })
});
Run Code Online (Sandbox Code Playgroud)

客户端

let customId = "your_custom_device_id";
socket.on("connect", () => {
    socket.emit('storeClientInfo', { customId: customId });
});
Run Code Online (Sandbox Code Playgroud)