Socket.io自定义客户端ID
我正在使用socket.io创build一个聊天应用程序,我想使用自定义的客户端ID,而不是默认的( 1120516437992682114
)。 连接时是否有任何方式发送自定义标识符,或只是使用某些东西来跟踪每个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
服务器对象的eio
和engine
来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); }); `