I'm developing a web game that currently all runs on one server. It uses SignalR to maintain connections between the server and clients, and the server also sends all the web stuff to clients (HTML/CSS/JS/etc.)
I've been thinking about how this would scale up if many more clients were to start using the site. Reading the SignalR documentation on scaling up, they suggest adding extra SignalR servers and linking them using a Redis backplane, or Azure's equivalent.
However, the example given in their diagram seems such a trivial use-case as to actually be rather misleading - it has a server sending a "hello" message and that being forwarded to all clients. You're almost certainly going to want more complexity than this, and some kind of state, whereas this example conveniently omits the need for any persisted state. If you have a chatroom, you'll want to check that a client trying to send a message has permission to send to that room, for instance. In my case, the client will need to be established as a member of the game before they can participate in it.
This introduces the concept of state, which appears to be entirely undealt with by the aforementioned documentation. Because state would be needed, a DB would be needed and that would need to be frequently accessed by all servers upon each client request, adding a significant overhead.
There's also the overhead of serialization and deserialization. If you have the concept of a chatroom, or a game room, and there is an associated state, it seems to me that the suggested 'scaling up' solution with a Redis backplane simply pushes the problem of maintaining state to the back end; servers will have to coordinate with each other - again presumably through a DB - to communicate the current state of the game, because you can't rely on one server being dedicated to dealing with that game and having it stored in its memory. This introduces a large serialization/deserialization and DB access overhead too.
It seems to me that a better scaling alternative for virtually any scenario is to design a system where each SignalR server is wholly responsible for maintaining the state of certain instances - such as a game or a chatroom - and that there be a central coordination server that tells clients which SignalR server to connect to. This would bypass the need for the kind of scaling mentioned in the SignalR docs completely, because a client would just be connecting to the one SignalR server responsible for dealing with that game/chatroom, and it would also avoid the serialization/deserialization overhead because the server wouldn't need to keep storing/restoring state to/from the DB; it could just be kept in memory.
Are there any significant disadvantages to scaling up in the way I've just mentioned? In what circumstances would it be better to scale up using the "Redis backplane" style scaling? It seems to me that virtually any system is going to need to maintain state, and that state either has to be communicated between SignalR servers introducing significant overhead, or stored in one server's memory meaning that scaling would be done simply by introducing new, separate SignalR servers that have certain states dedicated entirely to them. I actually wonder whether there are any scenarios where that type of scaling would be worse than the Redis backplane type scaling?