Socket.io Different Client IDs - node.js

I'm trying to make a simple multiplayer game using websockets and socket.io.
We've got most features working, and our problem now is finding out who the winning player is.
So the solution we're trying to implement right now is by getting sockets on run time, and when a player dies, they send a message to the server. The server on receiving this message adds a property 'dead' to the socket. So socket.dead = true is set when the player dies.
We then check a list of connected sockets (obtained dynamically) to see if there is only one remaining player alive (by checking if socket.dead is defined). One thing we realised is that the socket.ids of connected sockets actually change - and this is prooving to be a problem for us...
The question is where and when does the socket ids change, and how can we detect these changes so that we update our game data?
Thanks

You shouldn't check for the socket id, instead you should authenticate the user each time he connects to Socket.IO (socket.user = username).
Then instead of checking for the id of the players that are "alive", you can check for their usernames.
More on handling sessions with Express & Socket.IO here: http://www.danielbaulig.de/socket-ioexpress/

Related

How to store a turn based game state in Node.js

I am developing a turn based mobile game which is a question - answer game. Basicly server will send a question to players (there will be two players in a match) then player 1 answers this question after that, player 2 will be answering too the same question in a limited time order. Players could use jokers such as extend the time or change the question. This is the basic logic of my game. So here is my question:
I will be using Node.js and Socket.io for the server side. You know whether a player losts the connection to the server or simply kills the app starts again during in a match, they should be rejoin the same match and they should see what happened in the game when they were not there. How should i store the game state in my server?
My approach:
There will be a Game class that stores every state of the game and manages the countdowns for turns with setInterval method etc. and when the match starts i will create them and store like this:
activeGames[lobbyId] = new Game(player1, player2, lobbyId)
So for example if a player uses a joker i will catch that request inside the socket.io then retrive my class like this:
var yourGame = activeGames[lobbyId]
yourGame.useBonus(player1, bonusType)
So all the status of the game will be stored inside the class. But with this approach if my server dies or restarts etc. all active matches will be dropped. So that is not a good thing. What do you suggest about this problem? How my server should store the active matches?
Ps: Matches will be lasted for 3 minutes. After that i don't need the match history or something like that. So i am not looking for a persistent database solution.
Generally, you would generate a token (preferrably a cryptographically-secure one) for each client. When a client joins for the first time, generate the game data, and associate that data with the token. Then, send that token to the client. When the client reconnects, it can send that token back to the server, which then re-associates the data with the client.
As for server issues, there are many ways to go about things. What I'd do is create a folder called temp or session or something, then store each game in its own temp file. When the server restarts, it checks the temp folder for game files, loads them, then clears their temp files. You can add handlers for unhandledException and unhandledRejection in NodeJS to save currently active games to their own temp files before the server crashes or shuts down.

Socket can only communicate with one socket.io process

Hello i am trying to make a multiplayer game with nodejs and socket.io.
I am using multi process socket.io with cluster and socket.io-redis. It works well if you want to broadcast messages, emit etc.
But if i want to add some complexity in my code problems start to appear. I want my game to have a matchmaking function.
Assume this scenario:
Server find 2 users that want to play and start a game.
Users are on different processes on the same machine.
The problem is that a client can communicate with only one process the one that firstly got in.
So there are 3 possible solutions as I see it:
Matchmake with users that is on the same proccess --- Not good.
Create an ipc method between processes so the one with the target client can broadcast client's answer to the correct process --- Too complex and not sure if solves everything.
Change client's socket.io process to a new one without the user notice it --- Not sure if this is even possible.
Is there something i am missing here? Is there any other solution that i can't think?
Any help appreciated!
With socket.io-redis users can communicate even if they are in different servers/processes, this is why it exists.

Tell server that user is no more on internet

I am new to node.js and trying to develop group chat using node.js and socket.io. I am able to do group chat also able to manage data in the system.
Now, the problem with me is with offline users i.e not connected to internet.
I am having connection stream of this user and as if I do receiverUserSocket.emit("sendMsg",data) there is no way to verify if this user received message or not.
Yes, there is an event .on("disconnect") but I am getting delay of approx 30 - 40 seconds.
Is there any way we can identify that the user to whom we want to send message is online or offline.
The best way is to use socket.io heartbeats - assuming you're using socket.io.
Heartbeats and the problem with detecting a terminated connection are well explained here:
Advantage/disadvantage of using socketio heartbeats
Keep in mind that you can control heartbeat timeout values (thus forcing the disconnect event to appear much faster), as explained here:
Controlling the heartbeat timeout from the client in socket.io
But that might put much more strain on your server.

Keep socket.io room alive when all clients disconnect?

I have a multiplayer game with game rooms built in Node.js and socket.io. There are 4 players per game room and rooms are created when the first player joins. When I send data to a client connected to the room, I always perform the following check to make sure they're still in the room (sock_id is the socket ID of the client):
if(io.sockets.manager.rooms['/' + room].indexOf(sock_id) > -1){
...
}
If a player leaves the room, he is replaced by a robot player. However, I'm running into a problem when all 4 players disconnect. The room is automatically destroyed, and the above check throws an error cannot call method indexOf of undefined, indicating the room doesn't exist. One way to counter this is to add a check to make sure the room exists to every such check on the Node server (and there are quite a few).
But, I was wondering if it's possible to keep the room alive in some way even when all clients disconnect. I could then destroy the room when the game in question ends, and the problem is solved.

What is the best way to keep track of which users are online in nodejs?

So I am developing (more playing around with) a realtime game in node.js, I am also using Redis and Sockets.io. I have players create a lobby and join it (kind of like a pre-game chat room, where you can talk to players and select game settings) . The client is written in HTML/CSS/JS, Anyway I want to be able to tell when players disconnect from the lobby, to update the number of players joined on the interface (and joined player names).
Two options I have thought about are:
Using redis' key value timeout feature, to remove a particular field if it is not updated in x amount of time. I would then have the host check the existance of this field to check for DC's. I do wonder if this is highly inefficient, as many users potentially will be playing, so will it be bad to have many timeout values in redis and also many other users polling these fields.
I could use the sockets.io on('disconnect', ..) to update the field. However I am not sure if this event will fire if for example a users pc freezes?
Anyway I am open to any other ideas also!
Socket.io have a 'heartbeat' to check connection still alive. Default heartbeat timeout is 15s. You can read more about configuring it in this wiki. If heartbeat fails (user pc freezes) then socket.io will emit 'disconnect' event.
Socket.io should suffice. You can configure it to use heartbeats to ping the socket and check its health. If a user's computer freezes it will, in effect, not be able to respond to these heartbeats, causing it to force a disconnect.
To test this you could set up your Socket.io to use heartbeats, then connect via a browser onn a different computer. While in the browser past into the console an infinite loop. Causing it to simulate a freeze.

Resources