在socket.io中管理用户

在socket.io中管理用户,socket.io,Socket.io,我正在用socket.io编写一个游戏,为了管理游戏中的两名玩家,我有如下内容: let user1 = 1; let user2 = 2; io.on('connection', function(socket){ if (user1 === 1) user1 = socket; else if (user2 === 2) user2 = socket; socket.on('user_does_something', function(){ if

我正在用socket.io编写一个游戏,为了管理游戏中的两名玩家,我有如下内容:

let user1 = 1;
let user2 = 2;
io.on('connection', function(socket){

    if (user1 === 1) user1 = socket;
    else if (user2 === 2) user2 = socket;

    socket.on('user_does_something', function(){
        if (user1 === socket) {
            //do something for user1
        }
        if (user2 === socket) {
            //do something for user2
        }
    });

    socket.on('disconnect', function () {
        if (user1 === socket) user1 = 1;
        if (user2 === socket) user2 = 2;
    });

});

它是可行的,但这似乎是一种糟糕的方法,有没有简单的方法可以做到这一点?

这种方法是不可扩展的,因为您目前仅限于两个并发用户,这意味着如果您希望实现某种形式的大厅系统,即使您将两个并发用户限制在一个游戏中,您也只能运行一个并发游戏

相反,我建议使用
Map()
,您可以使用它来存储包含当前连接的客户机信息的客户机对象。您可以使用套接字对象的属性,例如
socket.id
,为每个用户形成标识符。另一个注意事项是,当我们传入
socket
对象时,我们已经知道事件是从哪个连接的用户派生的,因此当user one发出事件时,我们可以使用对象的
id
属性找到哪个用户发出了事件,如下所示

socket.on('user_does_something', function(){
    if (user1 === socket) {
        //do something for user1
    }
    if (user2 === socket) {
        //do something for user2
    }
});
此函数可以重构为

let connectedUserMap = new Map();

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

let connectedUserId = socket.id;
connectedUserMap.set(socket.id, { status:'online'});

    socket.on('user_does_something', function(){
        //do something
    });
}
这种处理用户的方法非常优越,因为您已经知道连接的用户,并且它减少了识别事件来源所需的逻辑

如果需要,我可以编写一个更好的示例,但这应该有助于改进代码

更新:

后端代码

let connectedUserMap = new Map();

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

let connectedUserId = socket.id;

//add property value when assigning user to map
connectedUserMap.set(socket.id, { status:'online', name: 'none' });

    socket.on('recieveUserName', function(data){
        //find user by there socket in the map the update name property of value
        let user = connectedUserMap.get(connectedUserId);
        user.name = data.name;
    });
}
前端发射:

emit('recieveUserName', {
//normally this would be dynamically added based on user input, but for examples sake
  name: 'user1'
});
为清晰起见,带有两个额外功能的长格式示例:

let connectedUserMap = new Map();

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

    let connectedUserId = socket.id;

    //add property value when assigning user to map
    connectedUserMap.set(socket.id, { status:'online', name: 'none' });


    socket.on('user_does_something', function(){
        //get access to the user currently being used via map.
        let user = connectedUserMap.get(connectedUserId);

        //do something.

    });

    //sets the user name for the user.
    socket.on('recieveUserName', function(data){
        //find user by there socket in the map the update name property of value
        let user = connectedUserMap.get(connectedUserId);
        user.name = data.name;
    });

    socket.on('disconnect', function () {
        //get access to the user currently being used via map.
        let user = connectedUserMap.get(connectedUserId);
        user.status = 'offline';
    });

    socket.on('someEventForAEveryone', function (data) {
        //data.msg - message to be output
        io.emit('message', "this is a test");
    });

    //example of sending another user a message
    //https://gist.github.com/alexpchin/3f257d0bb813e2c8c476 - reference
    socket.on('sendOtherClientMessage', function (data) {
        //data.id - the user to emit to.
        if(connectedUserMap.has(data.id)){
            socket.broadcast.to(data.id).emit('message', 'for your eyes only');
        } else {
            console.log("Client is currently not connected.");
        }
    })

};

假设用户发送了他们的名字,我想把它分配给socket.on('name',function(name){…})中的用户名变量;这看起来像什么?我已经更新了我的答案,显示了如何使用我上面概述的结构将名称分配给用户@Orion@Orion我刚刚更新了它,我已经完全重写了您现有的代码,并添加了两个函数以使其更清晰,希望这能让您开始:-)另一个问题,我如何在断开连接时从映射中删除该用户?@Orion您可以使用
connectedUserMap.delete(connectedUserId)
删除带有socketId的条目。