带有socket.io的node.js中的并发计时器

时间:2022-08-22 14:37:52

So I'm developing simple game with the following scenario:

所以我正在用以下场景开发简单的游戏:

  • 2 users need to start a game (so I'm creating new room for 3rd user and so on)
  • 2个用户需要开始游戏(所以我为第3个用户创造了新的空间,依此类推)
  • 2 users is maximum per room
  • 每个房间最多2个用户
  • When game is started, event is sent to client, after 60 seconds server needs to end the game.
  • 当游戏开始时,事件被发送到客户端,60秒后服务器需要结束游戏。

Code which I wrote will work only for 1 room, but for multiple rooms, cancelling is not correct because my lastRoom variable is incorrect.

我编写的代码仅适用于1个房间,但对于多个房间,取消不正确,因为我的lastRoom变量不正确。

I'm new to node.js so I'm not really sure how to deal with this.

我是node.js的新手,所以我不确定如何处理这个问题。

Some code:

一些代码:

var lastRoom = 'default'; //this is the first created room

function tryToStartGame(socket){

  var clients = io.sockets.adapter.rooms[lastRoom];

  console.log("Size of room "+lastRoom+" is: "+getObjectSize(clients));

  //we are checking size of last room
  if (getObjectSize(clients) == 2){

    //players in the room should be different
    games['default']= {
      'leftPlayer': getFromObject(clients, 0),
      'rightPlayer': getFromObject(clients, 1),
      'stuff': "some data here"
      'roomName': lastRoom
    };

    console.log("We can start the game");

    //let all the people in that room
    io.to(lastRoom).emit('game', games['default']);

    //game to cancel
    gameToCancel = lastRoom;

    //client needs to be aware when game is ended
    //but if we have simultaneous games this will not work
    setTimeout(function(){
      console.log("Cancelling game in: "+gameToCancel);
      io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");

    }, 8000); //after 8 seconds for test

    //reset the room name, so next time when this function is called in second room
    //we will have something different
    lastRoom = 'game'+new Date().getTime();
  }

  //we have less then 2 players, wait for another player
  if (getObjectSize(clients)<2){
    console.log("Less then 2 players");
    socket.emit('waiting', 'Waiting for another user to join the game');
  }

}

And tryToStartGame(socket) function is called always at connection like this:

并且tryToStartGame(套接字)函数总是在连接上调用,如下所示:

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

  //when client says he wants to play
  socket.on('joinGame', function(username){

    //add user
    addUser(socket, username);

    //send list of players
    io.emit('playersList', getFormatedPlayers());

    //figure out in which room this player bellongs
    socket.join(lastRoom);

    //try to start the game
    tryToStartGame(socket);

  });

Problematic part is that lastRoom variable is overwritten and then setTimeout picks the wrong room, so what happens that basically last game is canceled, and the previous ones are not.

有问题的部分是lastRoom变量被覆盖,然后setTimeout选择了错误的房间,所以基本上最后一个游戏被取消的情况会发生什么,而之前的情况则没有。

How should I correctly track and cancel the game in correct rooms ?

我该如何在正确的房间内正确跟踪和取消游戏?

1 个解决方案

#1


3  

As you noted, lastRoom is a global variable and might/will change between the time you set it and the timeout

如您所述,lastRoom是一个全局变量,可能/将在您设置它和超时之间发生变化

You can create a closure on the timeout function to keep the room as a locale variable:

您可以在超时函数上创建一个闭包,以将房间保持为区域设置变量:

var lastRoom = 'default'; //this has to be set in the same function than the call to setTimeout

//client needs to be aware when game is ended
//but if we have simultaneous games this will not work
setTimeout(function(){
  var gameToCancel = lastRoom;

  console.log("Cancelling game in: "+gameToCancel);
  io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");

}, 8000); //after 8 seconds for test

#1


3  

As you noted, lastRoom is a global variable and might/will change between the time you set it and the timeout

如您所述,lastRoom是一个全局变量,可能/将在您设置它和超时之间发生变化

You can create a closure on the timeout function to keep the room as a locale variable:

您可以在超时函数上创建一个闭包,以将房间保持为区域设置变量:

var lastRoom = 'default'; //this has to be set in the same function than the call to setTimeout

//client needs to be aware when game is ended
//but if we have simultaneous games this will not work
setTimeout(function(){
  var gameToCancel = lastRoom;

  console.log("Cancelling game in: "+gameToCancel);
  io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");

}, 8000); //after 8 seconds for test