0

So, as per usual, I am not sure what I am doing.

I want to make multiplayer games on the web using web sockets.

But of course I want there to be multiple game servers for horizontal scaling (I'm gonna hit it big)

Specifically for either Node.JS or ASP.Net (or both) how could I manage such a thing where there are 2 servers and 2 users. User A is assigned to server A by load balancer, and user B is assigned to server B. But they play in the same game?

Best I know of so far is to connect both game servers to a redis backing. But this seems like a convoluted way to communicate. I would rather have them both route to the game server (Whichever server the game starts on)

Comments
  • 1
    I believe socket.io has solutions for horizontal scaling. I haven't used it but read about it in the docs
  • 0
    Just speedballin here, maybe a lobby system could be easier than meshing
  • 1
    or have a matchmaking server which will then point the players to specific game servers. both will just be sockets, the last instruction that matchmaking will send to players is what gameserver to connect to.
  • 1
    Yeah, you need some sort of dispatcher, call it lobby, balancer, or whatever.

    I've used redis to save this state successfully before, but it's not the only option.

    In the end it's just a way to map specific clients to specific servers.
  • 0
    @Midnight-shcode @CoreFusionX in a technical sense, how?
  • 1
    @AlgoRythm two separate server-side apps. lobby is the one client connects to, and when the game is about to start, it sends to client ip+socket connection info for the actual game backend, which then client connecta to.

    lobby app keeps a list of those, so even though at first it can all run on the same backend and the "game connection info" will be the same as the lobby one, later if you add more servers, you add them to the list, and maybe even a way for game backends to talk to lobby backend to inform it about how busy they are to that libby backend can better decide which one to use for thw upcoming game.
  • 0
    @Midnight-shcode

    Beat me to it.

    In essence, that's it. It's fairly easy to do a PoC with redis.

    Your "game" servers announce themselves periodically (think RIP in routers, or SSDP announces) by creating a redis key with expiry time (to account for crashes preventing removal of keys).

    In this key you store whatever info might be necessary for the "lobby" server to route clients.

    Upon starting, and periodically, "lobby" servers query these keys. (Can use pubsub for that, left as exercise).

    That allows you to have horizontally scalable lobbies (think wow realms), and horizontally scalable game servers (with arbitrary mapping to lobbies, think wow dungeon instances).

    In addition, such an architecture solves broadcast overload by sharing the load, as in, if you send a payload to the lobby, which pubs to redis. Associated game servers are subbed to the channel, and then broadcast only to their connected clients.
  • 0
    This allows you to have a (more limited) way of communicating between clients in different game servers. (Think chats, etc)
  • 0
    @Midnight-shcode so how does it work at a code level. Say I have two docker instances running on one server. Instance A is the hub/lobby and B is the game server.

    I don't know why I can't find this anywhere online but I have no idea how I should be running the infrastructure and what the routing code should look like
  • 1
    Simple, make the lobby aware of the game server by any means you wish (https, was, redis, etc)

    Have the lobby keep a list of active servers along with whatever other info you need. (At the bare minimum, save ip and port of the servers).

    When clients connect, do pick one from the active servers (based on any criteria), and return the chosen server's address to the client (through a websocket). The client should then open *another* websocket to the game server and then do whatever your game does over that socket.
  • 0
    @CoreFusionX so it's required that each instance have its own address? I was hoping to avoid this
  • 0
    @AlgoRythm

    Hmmm, not necessarily. You mentioned having two docker instances in the same host. In that case, you need to set up some reverse proxy that will route clients to the correct game server based on "something" (like server name with vhosts) and still tell your clients what that something is.

    All in all, for networked games, I don't recommend using docker or sharing hardware. They are usually called dedicated servers for a reason. Keeping them in different hosts ensures faulty servers don't compromise the game, and that failure in distribution don't cause impact in all clients (as would be the case if one docker instance overloaded the host)
  • 0
    @CoreFusionX My resources are limited, but I want to build it in a scalable way if for no other reason than to learn how.

    I think vhost is a great term to research for now. I use nginx as a reverse proxy. I'll see what I can come up with. Thanks man 🤝
  • 0
    @AlgoRythm

    It's fine. Still, even if in the same host, each server must have a different port. That's part of the info that must be relayed.

    Vhosts, or virtual hosts, are a mechanism web servers use to share the same IP for different domains.

    DNS will solve multiple domains to the same IP, but apache/nginx/etc, will check the target URL of the incoming request, and route to a document root or another based on that.

    It's very much the same concept. Use a piece of information that's available to you, to dispatch to one "worker unit" (document root, game server, etc).

    Reverse proxies are the same too, but using balancing algorithms, which are more adequate to your use case.
  • 0
    @CoreFusionX right now I have multiple applications running on my one poor Frankenstein server using subdomains which nginx maps to a port internally. I'm thinking that I can do something similar here. I have no idea how this stuff works. I'm no network guy.
  • 1
    @AlgoRythm

    No need to. Focus on the basics. Expose a port range. Have game servers bind to a free port in that range.

    Know which ports game servers are listening on, and tell those to clients.

    It's not a networking problem (sure, it's the same as what reverse proxies or vhosts do), but you can solve it "by code", as you asked. Each game server knows which port it listens on. Tell that to your lobby, let the lobby inform clients where to find the game server.
  • 0
    @CoreFusionX hmm... I like that. I think running on random ports looks ugly, but if it's just a web socket connection, nobody will even see it
Add Comment