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.
Related
I'm making a game in which users can register and game starts at fixed time by (pair of 2) pairing users from the pool of players. I'm not able to understand how can I emit the start_game event for the game to start once the pairing is done as one player can be offline at the start of the game but the game needs to start and timeout the offline player.
I'm not able to understand how can I emit the start_game event for the game to start once the pairing is done as one player can be offline at the start of the game but the game needs to start and timeout the offline player.
Here's one way to approach it. Send the user a start_game message. Set a setTimeout() for whatever your timeout time is. When the client receives the start_game event, the client needs to immediately respond with something like start_game_received. If you don't get a start_game_received before the setTimeout() fires, then time out that user and revoke their match making. When the start_game_received is received, you check if the timer is running. If it is, you cancel the timer.
This requires keeping a bit of server-side state for a given user. You can do that with a custom property on their socket.io socket that contains an object with their state in it. For example, you can store the timer there and a boolean indicating whether they've already been invited to a match or not.
Every time a socket joins a room is created in my application. Is this normal behavior?
I am not creating these rooms, as you can tell the room name is called the ID of the socket, which I find weird. Is this normal behavior?
This is normal behavior. Socket.io creates a room with the name of the connection's socket.id and automatically places only that socket in the room. This allows you to do things like:
io.to(someSocketId).emit(...)
because the socket.id is also a room name. Since socket.id values are unique and random and because all room participation is controlled by the server only, it's really just a server housekeeping thing that doesn't affect anything else.
If you have some reason to want to be able to discern which rooms are ones you created and which ones are the automatic socket.id form, you can put a unique prefix on the ones that you create such as an underscore and then you can tell which ones are yours and which ones are created by the system.
When the connection disconnects, that room will also go away.
Im starting out with node.js and socket.io.
I have 2 questions:
- When a room is empty, is it automatically destoyed unbtil recreated?
and if it is not destroyed automaticaly, does it take up much ressources on the server?
on the server side. is it the io server or the connected socket that should transmit the data?
socket.emit('doSomething');
or
io.emit('doSomething');
The room is automatically removed from the array and the nodeJSs' V8 Garbage Collector finishes the job of completely removing the room from ram. You don't have to worry about any of that. Remember that all users are automatically put on a room on joining the server ( the socket.id named room ). io.emit should be used when you want to send a message from the server to anyone and socket.emit should be used when you want to send a message only to the sender. More information can be found on this answer: https://stackoverflow.com/a/40829919/7868639
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/
I am building a massively multiplayer game with Node.js and Socket.io. All players will move around on the same infinite map (think Minecraft). As the player moves I load the tiles that are visible to them. When players move their movement should be sent to all the players that can see them.
My question is; how should I go about structuring my sockets? Having one socket for all players doesn't seem like it would scale. I could shard the world into chunks, but I'm not sure how to manage the chunk boundaries. Since most players won't be able to see each other most of the time I'd prefer that each player's socket only get updates that are relevant to them.
I've read that Socket.io has a concept of "rooms" which are just sockets that get the same messages. Would it be feasible to have a separate room for each connected player to which I would add the socket of any other player who moves nearby? Then each time the player moved I could send a message to that room. How then could I manage when viewers leave or join the room?
Obviously this is a vague question, but I'm just looking for best practice advice. Links to articles on the subject would be appreciated.
This is one of the essential problems in designing MMO servers. Generally you want a socket per client and you implement logic to subscribe a client to a particular region.
Regions are a good way of setting up 'channels' to control data subscription. You could have discrete names for each region and use Socket.io rooms to subscribe players to a region.
After all this is going, things get much easer to handle. So if a player moves in a particular region, all the server has to do is send that 'Player Moved' event to all subscribers of all regions within X meters of the event.