Socket.io custom client ID

后端 未结 11 835
栀梦
栀梦 2020-12-04 07:59

I\'m making a chat app with socket.io, and I\'d like to use my custom client id, instead of the default ones (8411473621394412707, 1120516437992682114

相关标签:
11条回答
  • 2020-12-04 08:23

    Can store customId (example userId) in object format instead of for loop, this will improve performance during connection, disconnect and retrieving socketId for emitting

    `

     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);
        });
    `
    
    0 讨论(0)
  • 2020-12-04 08:24

    If you are trying to use a custom id to in order to communicate with a specific client then you can do this

    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")
    });
    
    0 讨论(0)
  • 2020-12-04 08:27

    why not a simpler solution that does not need to maintain an array of connected clients and does not override internal socket 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);
        })
    });
    

    Client side

    let customId = "your_custom_device_id";
    socket.on("connect", () => {
        socket.emit('storeClientInfo', { customId: customId });
    });
    
    0 讨论(0)
  • 2020-12-04 08:29

    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);
    };
    
    0 讨论(0)
  • 2020-12-04 08:29

    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
    });
    
    0 讨论(0)
  • 2020-12-04 08:30

    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.

    0 讨论(0)
提交回复
热议问题