I've been wondering a lot lately about how to make an optimised server structuration, and i came to the conclusion that i severely lack knowledge on the subject.
I'll be doing this with either C, C++ or C#, with a preference for the latter.
Context:
I have a server that can operate more than 3K clients at one time.
This server is a game server, hence it only receives key inputs from the clients, for security measures.
Therefore the server is doing every operation on the user's data, and send back enough information to the client in order to display a personal GUI. (The server is of course a console application, don't get me wrong.)
Approaches:
1- 1 Client = 1 Logic Thread
(The thread does the player calculation)
Pros: every client runs his own server code, the server is more responsive to a particular client's request.
Cons: I do not have the insurance that a particular client will iterate its code 14 times while another would have iterated it 10, (so the two players, side by side, if it was for a movement operation, can become 4 squares afar, which should not be the case, as every player should move at an exact same speed)
Locking every thread to perform actions until a next logic loop happens can be quite devastating if something bad happens on any of the client, leading to severe lags in worst cases.
2- 1 Client = 1 Entry Thread, Main logic loop
(The thread receives the keys pressed by its client)
Pros: As the logic is all in the same loop, there is no desynchronization problems anymore.
Cons: Iterating ALL the game logic in one loop will most probably cause severe latency if the operations becomes advanced.
Moreover, if many clients are to catch up with all the current data being processed (sudden peak of connections), it would also cause additional latency, a partial solution would be to retrieve those datas in the Entry Thread.
3- 1 Client = 1 Entry Thread, X Logic threads, 1 Logic Thread synchronizer
(Entry thread receives keys, register the client in the concerned threads (One for each kind of action (Moving, Acquiring user data, Battle, Etc...)), Those threads gives the information whenever they can, and the Logic thread synchronizer ensures that tasks that needs to be "Ordered" in time are ordered.)
Pros: Share computation resources among all the Logic Threads, ensuring minimum latency for clients.
Cons: High vulnerability to resources concurrency, and if a particular task is done faster than another task that is to be synchronized with it, becomes as slow as the latter.
Question:
As i said earlier, i certainly lack knowledge about networking, threading, and concurrency, to efficiently order the structure of my program. Therefore, I'm asking it here:
What would be the best approach to take, and how should the global skeleton should be ordered to minimize latency, and permits a large number of synchronous users to play on the server.
Additional information
Maybe a bit of information about the idea behind this all will help.
My goal here is to create a server that will be used to run a simple RPG, which needs to have movement synchronization on the map (old school square-to-square movements), turn by turn instanciated battle (e.g. Dragon Quest, Final Fantasy, Pokemon), and exchange of user data (seeing X's profile, see how many monsters he killed, his guild, etc.)
If i'm asking for more than 3K clients at the same time, it is because i do not want to make a pile of junk that holds in place by a miracle. I want to further my knowledge on networking and its applied logic, would it be programmative logic or structuration logic.
So basically the problem is "Having a maximum of clients, on a minimally powerful server, therefore optimizing it as much as possible."