Splendid
Splendid

Reputation: 1357

Concurrent timers in node.js with socket.io

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

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

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

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:

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.

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

Upvotes: 0

Views: 2039

Answers (1)

Xavier
Xavier

Reputation: 1207

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

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

Upvotes: 3

Related Questions