Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Server Architecture - Redis vs Socket server

I have a game server which is going to run on a few instances.

World 1, World 2, World 3

Each world is a server that runs on a different IP Address.

There is a list of what the game should have:

  • Connection to the game, authenticating the user.
  • Ability to see all connected players, display what world each player is connected to.
  • Ability to message a player, even if hes connected to a different world server.
  • Ability to send global message to all servers.

There are two approaches to make this that I can think of:

Approach 1 - Login Server TCP/IP

  • Create a middle-man server. When a client connects to a world, that world server will send a login request packet for the entered user credentials and the login server will check against the database and respond with the result of the authentication, if succeed, the user will be authorized in the world.

  • Login Server will always update all worlds with the list of the online players, and the state of each player, what world he is on, etc.

  • When sending a message to player Y from player X when both are on different worlds, the world server will send a message to login server, and login server will pass it to the target world of that player so the player in the other world will receive the message.

IMG]([![enter image description here

Approach 2

Work the same as approach 1 but instead of a login server, have an HTTP API server, and update each other with events using Redis server. Why do I think that this is better? Because it will be easier to integrate a web application to the game, so allow users connected and chat with each other via a web application.

In order to do that in approach 1, you need to add a new tunnel to your TCP/IP login server to support WebSocket connections.

enter image description here

Sorry for the bad drawings.

Is approach 2 possible? What do u think is a better approach and if there is some other approach you can think of?

like image 783
Ben Beri Avatar asked Mar 27 '19 11:03

Ben Beri


1 Answers

There are many considerations that you haven't given us, but I will try to give a general answer. A typical way to do something like this is with a Load Balancer, which distributes the initial connection across the machines (Worlds) at the backend. You didn't say if users are supposed to connect to a specific world, or just any one. There are ways to make the Load Balancer be sticky, but you might want a different approach, if say, if user get to choose their world upon login. In any case it might look like this:

Block Diagram with Load Balancer

You would then use the Database for login credentials, which each world would verify for each login. You would then user Redis (you could use the database, but Redis is faster) to track current users, which world they were on, etc. You could also use it to send messages, or you could a message queue (with a source/sink for each world). This method is also very scalable. If you need more worlds, just add more of the exact same machine behind the load balancer, without having to change any code.

As I said, this is just a general answer, and the specifics of your situation may make other approaches more attractive.

like image 196
SolverWorld Avatar answered Oct 26 '22 18:10

SolverWorld