I'm making a board game in which users register for a game which will start at fixed time and users can register till the start of the game. My initial idea was to use it with socket.io(connection sets up when user opens up the app and use same socket for gameplay) with Redis adapter and fire start game event from outside the context of sockets (using redis adapter and separate process). But my friend suggested to use ws with in-memory state management(for making stateless and not use socket.io for performance) and use polling for showing registering tournaments. Can you please help me with if I'm missing out anything ?
There are several options to use. I'll go through some of them here.
Stateless vs Stateful
Stateless servers do not hold any state by themselves. When an event happens (a request or a message from network arrives) the server fetches data from a database using data from the event (player ID, message ID, etc), processes the request and then possibly sends a response.
The state is not stored primarily in the server's memory and will not be lost if the server is rebooted. This allows easy scaling for multiple users as all the data is stored elsewhere and can be fetched by any server instance.
Fetching the data every time from a database adds delays and is not in general well-suited for fast-paced real-time games. But it works really well for game lobby features such as matchmaking and user management. This delay can be reduced a little bit by using a common cache server like Redis.
This type of server manages the state by itself in the server's own memory. For example it may hold the current game state which is lost if the server is rebooted, unless the server is allowed to gracefully quit and save it's state to disk or database.
Scaling up for more concurrent users who need to interact with each other is harder as it would require the servers to transfer data between each other through P2P or a database or other means. In general this approach supports best serving a small group of users that need to interact with each other.
As stateful server stores the data in it's memory, it is well-suited for fast-paced gameplay with relatively short sessions. These types of servers are also often started up and shut down on demand as the amount of total players in the game requires.
Redis is a database that can be used for in-memory caching before fetching from the actual database. It does save data to disk periodically, but it is not guaranteed to keep the data safe. If you want to keep data safe, something else is recommended as a database. For short-term usage this is a great database.
These types of databases are great for storing data long-term and are used for stateless server databases. However fetching data from these databases adds delay to processing requests or events.
Different ways to transfer data
This works with HTTP(s) protocol and your client makes a HTTP request to your server every time data is transferred. In general you have to poll to fetch data with this method. Because you need to poll data from the server, this is not well suited for real-time gameplay. If your game can tolerate a delay of second or two, then this approach may work for you.
These work almost just like TCP sockets. You create a connection to a server and that connection is kept alive until your client ends the session. In general WebSockets use event-based communications and either of the connected ends can send data at any point through the socket, no polling is required. This supports real-time applications really well, but because they use TCP under the hood they are not best suited for a very fast-paced gameplay (like a FPS game, Counter-Strike for example). If your game can tolerate a delay of hundreds of ms then this approach may work for you.
Almost the same as Websockets, but you need to implement certain stuff yourself, like keepalive. Websocket uses TCP under the hood. I would recommend this over Websocket only if you really know you need it.
TCP makes sure your network packets arrive to the destination and in correct order. This means, if there is a hiccup in the network somewhere between you and the other end, there may be significant delays.
UDP sockets are "connectionless" sockets and you need to handle a lot of things yourself, but this allows even faster message processing. UDP packets are not kept in order and they may arrive to the destination in different order than how they were sent if they arrive at all. This works really well for applications that require very small delays, like very fast-paced shooter games.
- Express is a great tool to serve REST API requests with Node.js
- Websocket package in npm works well for Node.js
- Protobuf is really good layer for managing and serializing your messages with sockets (Websocket, TCP, UDP) if you are not able to share code between the client and the server
- BSON is like "binary JSON" which you can use to serialize your data and send them over the network in efficient manner with sockets
This really depends up on your own requirements which you did not really specify that much other than the game being a board game, but for what I can gather from your question I would use websockets along with a combination of two different servers, one to act as a lobby for matchmaking, and then another for the gameplay. Both servers could use stateless approach and websockets, and they can be combined in to one server if you prefer to do so.
Personally I have not used Socket.io and I have no clue what are the performance implications of that. But from a quick look at it I see it takes equal amount of effort to set up websockets, which allows you to design your own protocol (with BSON for example) or to use Protobuf for data transfers.
I hope this answers at least some of your not very specific questions.