Socket.io custom client ID
In the newest socket.io (version 1.x) you can do something like this
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
});
To set custom socket id, generateId function must be overwritten. Both of eio
and engine
props of Socket.io
server object can be used for to manage this operation.
A simple example:
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
})
It seems to be it has been handled.
It must be in mind that socket id must be unpredictable and unique value with considering security and the app operations!
Extra: If socket.id
is returned as undefined
because of your intense processes on your generateId
method, async/await
combination can be used to overcome this issue on node.js
version 7.6.0 and later. handshake
method of node_modules/engine.io/lib/server.js
file should be changed as following:
current:
// engine.io/lib/server.js
Server.prototype.generateId = function (req) {
return base64id.generateId();
};
Server.prototype.handshake = function (transportName, req) {
var id = this.generateId(req);
...
}
new:
// 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);
...
}
Note: At Engine.io v4.0, generateId
method would accept a callback. So it would not needed to change handshake
method. Only generateId
method replacement is going to be enough. For instance:
io.engine.generateId = function (req, callback) {
// some intense id generation processes
// ...
callback(id);
};
You can create an array on the server, and store custom objects on it. For example, you could store the id created by Socket.io and a custom ID sent by each client to the server:
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;
}
}
});
});
in this example, you need to call storeClientInfo from each client.
<script>
var socket = io.connect('http://localhost', {port: 8080});
socket.on('connect', function (data) {
socket.emit('storeClientInfo', { customId:"000CustomIdHere0000" });
});
</script>
Hope this helps.