繁体   English   中英

Socket.io 自定义客户端 ID

[英]Socket.io custom client ID

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

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

        });
    });

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

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

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

希望这可以帮助。

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

一个简单的例子:

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
})

好像已经处理好了。

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

额外:如果socket.id由于您对generateId方法的密集处理而返回为undefined ,则可以使用async/await组合来解决node.js 7.6.0 及更高版本上的这个问题。
node_modules/engine.io/lib/server.js文件的handshake方法应更改如下:

当前的:

// engine.io/lib/server.js

Server.prototype.generateId = function (req) {
  return base64id.generateId();
};

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

新的:

// 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);
  ...
}

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

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

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

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

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

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

var lookup = clients[customId];

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

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

      socket.id = "YOUR_CUSTOM_ID";
});

你可以在数组下看到:

io.sockets.sockets

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

客户端

let customId = "your_custom_device_id";
socket.on("connect", () => {
    socket.emit('storeClientInfo', { customId: customId });
});

这将适用于2.2.0 及更高版本的 Socket.IO

要设置自定义 Socket Id,必须覆盖generateId函数。

一个简单的例子:

服务器端

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

io.use((socket, next) => {
  io.engine.generateId = () => {
    // USE ONE OF THESE
    socket.handshake.query.CustomId; // this work for me
    // return socket.handshake.query.CustomId;
  }
  next(null, true);
});

io.on('connection', function (socket) {
    console.log(socket.id);
})

克林特·赛德

io.connect(URL, { query: "CustomId = CUSTOM ID IS HERE" })

注意:请记住,socket id 必须是唯一值。

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

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

可以以对象格式而不是 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);
    });
`

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM