在socket.io中管理用户

时间:2017-04-10 06:51:28

标签: socket.io

我正在用socket.io编写一个游戏,为了管理游戏中的2个玩家,我有一些看起来像这样的东西:

!silent               : Switch On/Off silent mode     
!grep                 : Filter lines by regular expression
!igrep                : Filter lines by regular expression, case-insensitive
!grep_format          : Do regular expression searching, output formatted result upon captured groups
!igrep_format         : Do regular expression searching, output formatted result upon captured groups, case-insensitive
!grep_formatx         : Do regular expression searching, output formatted result upon captured groups, then execute formatted string as windbg commands
!igrep_formatx        : Do regular expression searching, output formatted result upon captured groups, case-insensitive, then execute formatted string as windbg commands

它有效,但它似乎是一种可怕的方式,有一个简单的方法来做到这一点吗?

1 个答案:

答案 0 :(得分:0)

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

相反,我建议使用Map(),您可以使用它来存储保存有关当前连接的客户端的信息的客户端对象。您可以使用套接字对象的属性(例如socket.id)来为每个用户形成标识符。另一个注意事项是,当我们传入socket对象时,我们已经知道事件已经派生的连接用户,所以当用户发出事件时我们可以找到哪个用户使用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;
    });
}

frontend emit:

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

};