Javascript Socket.io 自定义客户端 ID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7702461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:14:56  来源:igfitidea点击:

Socket.io custom client ID

javascriptnode.jssocket.io

提问by pmerino

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). Is there any ways of sending the custom identifier when connecting or just using something to track a custom name for each ID? Thanks!

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

回答by oscarm

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:

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

        });
    });

in this example, you need to call storeClientInfofrom each client.

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

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

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

Hope this helps.

希望这可以帮助。

回答by efkan

To set custom socket id, generateIdfunction must be overwritten. Both of eioand engineprops of Socket.ioserverobject can be used for to manage this operation.

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

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 unpredictableand unique value with considering security and the app operations!

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

Extra:If socket.idis returned as undefinedbecause of your intense processes on your generateIdmethod, async/awaitcombination can be used to overcome this issue on node.jsversion 7.6.0 and later.
handshakemethod of node_modules/engine.io/lib/server.jsfile should be changed as following:

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

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, generateIdmethod would accept a callback. So it would not needed to change handshakemethod. Only generateIdmethod replacement is going to be enough. For instance:

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

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

回答by Salvador Dali

In the newest socket.io (version 1.x) you can do something like this

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

回答by James Westgate

I would use an object as a hash lookup - this will save you looping through an array

我会使用一个对象作为哈希查找 - 这将节省您遍历数组

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

var lookup = clients[customId];

回答by Aviram Netanel

or you can override the socket id, like this:

或者您可以覆盖套接字 ID,如下所示:

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

      socket.id = "YOUR_CUSTOM_ID";
});

you can see under the array:

你可以在数组下看到:

io.sockets.sockets

io.sockets.sockets

回答by Aviram Netanel

Do not change the socket IDs to ones of your own choosing, it breaks the Socket.io room system entirely. It will fail silently and you'll have no clue why your clients aren't receiving the messages.

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

回答by Marco Grassi

why not a simpler solution that does not need to maintain an array of connected clients and does not override internal socket id?

为什么不是一个更简单的解决方案,它不需要维护一组连接的客户端并且不覆盖内部套接字 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 });
});

回答by Patrick Battisti

With this 2.2.0version of Socket.IO, you can achieve this.

有了这个2.2.0版本的 Socket.IO,你就可以做到这一点。

io.use((socket, next) => {
  io.engine.generateId = () => socket.handshake.query.token;
  next(null, true);
});

回答by partikles

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

可以以对象格式而不是 for 循环存储 customId(例如 userId),这将提高连接、断开连接和检索 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);
    });
`

回答by Ahmadposten

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

如果您尝试使用自定义 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")
});