Advertisement

Which MOBA lobby architecture is better?

Started by July 19, 2017 02:55 PM
9 comments, last by hplus0603 7 years, 2 months ago

Hi everyone,

I am currently designing a MOBA game for android platform and I have a few problem with the backend. On the MOBA game lobby, which is the better solution?

1. Game clients will get a lobby server's IP address by HTTPS POST request to the backend web service. The game clients will connect directly using TCP sockets to the dedicated lobby server. From there, the game clients can login and the lobby server will deal with all the incoming request from the game clients.

2. There will be a hard coded IP address of a TCP load balancer (E.g. Amazon Load Balancer) in all game clients. The game clients will just connect to the load balancer and let the load balancer choose which lobby server to handle the future requests.

3. Similar to 1, should all the lobby server have access to the game database or should all the lobby server do a HTTP request to the backend web service to get whatever data the lobby server wanted?

I'm assuming the question you're trying to solve in 1/2 is "how do clients find the lobby server to talk to ?"

Hard-coding IP addresses is a really bad idea, because even if you have a "static IP," you will sometimes be forced to change because of ISP re-organization, or you may want to change ISPs, or whatnot.

Returning raw IP addresses from POST requests is slightly less bad, but still have problems for users that require transparent proxies with DNS masquerading, or if you grow to the scale that you want to do regional IP balancing, for example.

The solution that the internet is designed around is options 3:

You define a domain name for your lobby server, such as "lobby.mygame.com" and let clients connect to this name. The DNS infrastructure is robust, well understood, and highly compatible across the world.

I'm assuming the question you're trying to solve in 3 is "how does a lobby server know who a player is and what their stats are?"

Lobby servers are just another kind of application servers. You can build a two-tier system (lobby servers talk to your databases) or a three-tier system (lobby servers talk to web API servers talk to databases) depending on how much effort you want to spend on it.

If a user logs in on a website first, you may want that website to generate a session token. Typically, some tuple containing user id and token issue time, as well as a HMAC of user-id:issue-time:server-secret. When a client connects to another server in your cluster, they can provide this session token, and the server can verify that the time is reasonable, and that the HMAC matches when given the server secret (that the client doesn't know) and thus the user-id is also legitimate. This way, the client doesn't need to keep sending its password to the servers.

If the users log in to lobby servers right away, then you can make the lobby servers issue the same kind of ticket, or you can just structure your TCP protocol to require authentication up-front (name+password.) Presumably you use TLS for this.

 

enum Bool { True, False, FileNotFound };
Advertisement

Thank you for replying so fast @hplus0603.

I wanted to create a lobby system similar to Clash Royale' lobby. By using wireshark to inspect their traffic, I saw all TCP packets when you do anything at the lobby and once after matchmaking is done, they switch to UDP for low latency. My current backed architecture is:

1. Client will login through WebAPI and request for a few lobby servers IP address

2. The WebAPI will issue a session token like you mention along with the list of a few available lobby server IP address to the client. The client will try to connect directly via TCP socket to the lobby server. BTW I am using Sodium library for public key exchange method get a common shared key between the client and the lobby server before encrypting all the traffic with it. Although strong hacker might get through the encryption, I will have strong packet authentication to combat MITM attack.

3. Once client has connected to the lobby server, client will send the session token to the lobby server to verify if it is a legitimate client.

4. From then, the all lobby related request will go through the lobby server and lobby server will have access to the database to grab any client data it want.

Is there any recommendations or improvement to this architecture?

Using tested libraries is good. Generally, the attack against a game focuses on the player and the player's device, or perhaps the servers, rather than the connection in between.

When returning "a few IP addresses" from the web server, I'd suggest returning DNS names might be more standard than returning IP addresses.

Other than that, what you do can work fine.

 

enum Bool { True, False, FileNotFound };

Hm.

For example, in our MOBA game clients don't have access to lobby/match maker directly. When players login, they connect to game server instance. And this instances have access to MM (they find it in private network using consul.io - tool for service discovery).

But if you want to make MM/lobby public, hide it behind load balancer, at least.

What's the benefit of connecting to the game server first? How can you send all the players that end up in the same match to the same server that way? Or do you only have one game server?

enum Bool { True, False, FileNotFound };
Advertisement
1 hour ago, hplus0603 said:

What's the benefit of connecting to the game server first? How can you send all the players that end up in the same match to the same server that way? Or do you only have one game server?

1) Player sends request to on of Auth servers. Get token.

2) With token sends requests to one of api servers. Api finds server/node with free space, send req to this node. On this node we create room for user. And send back info about this server to api, which sends this info to client.

3) Player connects to this game instance.

4) When players want to play, they send request to their servers (game instances). This servers send request to Match Maker(MM). There happens some magic. At the end MM trying to find free server; and here we create arena room. Send back info about it to MM, MM sends this info to instances. Instances send info to players.

5) Now players can connect to same instance and play together.

That's it.

Why is the player connected to a temporary room while waiting for matchmaking? Is there actual gameplay available there, or is it just a convenient way of setting up the game? Are you using Unity? (I know it often causes these kinds of multiple round trips.)

 

enum Bool { True, False, FileNotFound };
6 hours ago, hplus0603 said:

Why is the player connected to a temporary room while waiting for matchmaking? Is there actual gameplay available there, or is it just a convenient way of setting up the game? Are you using Unity? (I know it often causes these kinds of multiple round trips.)

 

This is not "temporary room".Yes, here is the city-builder part. Game server instances and client on Unity3d. MM on Java.

 

You can check our trailer (:

 

Ah, so you actually have gameplay before the matchmaking happens. Thanks for clarifying!

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement