I'm trying to make a two player competitive maze game using socket.io. To ensure that both players get the same maze, I want to send a seed to both clients, where the client then generates a maze based on said seed. However, when the second player joins, only the first player (who was already in the room) receives the emission.
Here is the relevant server-side room and seed emission code:
// Find and join an unfilled room
var roomID = 0;
while (typeof io.sockets.adapter.rooms[roomID.toString()] !== 'undefined' && io.sockets.adapter.rooms[roomID.toString()].length >= 2)
roomID++;
socket.join(roomID.toString());
console.log('A user from ' + socket.conn.remoteAddress + ' has connected to room ' + roomID);
// Seed announcement
if (io.sockets.adapter.rooms[roomID.toString()].length == 2) {
var seed = Math.random().toString();
socket.in(roomID).emit('seed', seed);
console.log("announcing seed " + seed + " to room " + roomID);
}
socket.on('seedAck', function(msg) {
console.log(msg);
})
On the client side, I have some code to respond back to the server with the seed, to find out if they're receiving the seed properly.
socket.on('seed', function(msg) {
// Some other code here...
socket.emit('seedAck', 'client has recieved seed ' + msg);
});
Here is what the server sees:
A user from ::1 has connected to room 0
A user from ::1 has connected to room 0
announcing seed 0.936373041709885 to room 0
client has received seed 0.936373041709885
To verify that only the client that was already in the room received the seed, I refreshed the first client, and this time only the second client received the seed.
I believe what's happening is that the server is sending the seed before the second client is ready. However, after multiple Google searches, I could not come to a solution. I was considering adding a button to the client, requiring the user to press the button first (and thus ensuring that the client is ready), but then it requires some tedious bookkeeping. I've also considering some sort of callback function, but I haven't come to a conclusion on how to properly implement it.
Is my only option to manually keep track when the both clients are ready, or is there a better solution that's integrated within socket.io?
Edit: I've attempted modified my code so that it waits for both clients to send a message that they're ready before sending the seed. Server-side, I have this:
socket.on('ready', function(msg) {
console.log(msg);
// Seed announcement
if (io.sockets.adapter.rooms[roomID.toString()].length == 2) {
var seed = Math.random().toString();
socket.to(roomID).emit('seed', seed);
console.log("announcing seed " + seed + " to room " + roomID);
}
});
while client-side, I now have this:
socket.on('seed', function(msg) {
// Some other code here ...
socket.emit('seedAck', 'client has received seed ' + msg);
});
socket.on('connect', function() {
socket.emit('ready', 'client is ready!');
});
However, the same problem persists, as shown by the server output:
A user from ::1 has connected to room 0
client is ready!
A user from ::1 has connected to room 0
client is ready!
announcing seed 0.48290129541419446 to room 0
client has received seed 0.48290129541419446
The second client still does not properly receive the seed.