Socket.io自定义客户端ID

我正在使用socket.io创build一个聊天应用程序,我想使用自定义的客户端ID,而不是默认的( 1120516437992682114 )。 连接时是否有任何方式发送自定义标识符,或只是使用某些东西来跟踪每个ID的自定义名称? 谢谢!

       

网上收集的解决方案 "Socket.io自定义客户端ID"

您可以在服务器上创build一个数组,并在其上存储自定义对象。 例如,您可以将由Socket.io创build的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; } } }); }); 

在这个例子中,您需要从每个客户端调用storeClientInfo

 <script> var socket = io.connect('http://localhost', {port: 8080}); socket.on('connect', function (data) { socket.emit('storeClientInfo', { customId:"000CustomIdHere0000" }); }); </script> 

希望这可以帮助。

在最新的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 }); 

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

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

要设置自定义套接字ID,必须覆盖generateId函数。 可以使用Socket.io 服务器对象的eioengine来pipe理这个操作。

一个简单的例子:

 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必须是不可预知的 ,并考虑到安全性和应用程序操作的独特价值!

额外的:如果由于你的generateId方法激烈的进程, socket.id被返回为undefined的, async/await组合可以用来解决node.js 7.6.0及更高版本中的这个问题。
node_modules/engine.io/lib/server.js文件的handshake方法应该改变如下:

前任的:

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

新:

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

或者你可以覆盖套接字ID,就像这样:

 io.on('connection', function(socket){ socket.id = "YOUR_CUSTOM_ID"; }); 

你可以看到下面的数组:

io.sockets.sockets

不要将套接字ID更改为您自己select的套接字ID,它完全打破了Socket.io机房系统。 它会失败默默,你不知道为什么你的客户没有收到消息。

如果您正尝试使用自定义ID来与特定客户端进行通信,则可以执行此操作

 io.on('connection', function(socket){ socket.id = "someId" io.sockets.connected["someId"] = io.sockets.connected[socket.id]; // them emit to it by id like this io.sockets.connected["someId"].emit("some message", "message content") }); 

可以以对象格式存储customId(例如userId)而不是for循环,这将改善连接期间的性能,断开和检索用于发射的socketId

`

  var userId_SocketId_KeyPair = {}; var socketId_UserId_KeyPair = {}; _io.on('connection', (socket) => { console.log('Client connected'); //On socket disconnect socket.on('disconnect', () => { // Removing sockets let socketId = socket.id; let userId = socketId_UserId_KeyPair[socketId]; delete socketId_UserId_KeyPair[socketId]; if (userId != undefined) { delete userId_SocketId_KeyPair[userId]; } console.log("onDisconnect deleted socket with userId :" + "\nUserId,socketId :" + userId + "," + socketId); }); //Store client info socket.on('storeClientInfo', function (data) { let jsonObject = JSON.parse(data); let userId = jsonObject.userId; let socketId = socket.id; userId_SocketId_KeyPair[userId] = socketId; socketId_UserId_KeyPair[socketId] = userId; console.log("storeClientInfo called with :" + data + "\nUserId,socketId :" + userId + "," + socketId); }); `