Advertisement Jump to content
Sign in to follow this  
Relfos

MMO Server questions

This topic is 1858 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am implementing a MMO server using TCP. Well, this server was already implemented before, but in single threaded way, and of course did not scale properly.

The single threaded version just polled all player sockets constantly, and the response times were atrocious with more than 15 players online.

 

So now, I decided to modify it to create a new thread for each player that connects, and use blocking sockets instead of polling.

First question, is this scalable enough? What kind of limit can I expect?

I usually heard that MMO servers usually cap out at 2000 online players per server, could I reach this kind of value by using one thread per player.or the cpu would bottleneck too much?

My server is installed on Amazon EC2, so bandwidth wont be a problem, the performance will all depend on my implementation.

 

Second, how to detect when one client dropped the connection in TCP.

Let's say that one thread on the server is blocked on socket.Read() and the client just dropped the connection (for example, crashed ).

How should this be handled, does the blocking read() interrupts if the connection is dropped or it hangs there until the thread is killed by the main thread?

In the current implementation, since the sockets do not block, the server just keeps track of the timestamp of the last message received and drops the connection when too much time passes without new messages.

Edited by Relfos

Share this post


Link to post
Share on other sites
Advertisement

I am implementing a MMO server using TCP. Well, this server was already implemented before, but in single threaded way, and of course did not scale properly.
The single threaded version just polled all player sockets constantly, and the response times were atrocious with more than 15 players online.
 
So now, I decided to modify it to create a new thread for each player that connects, and use blocking sockets instead of polling.
First question, is this scalable enough? What kind of limit can I expect?
I usually heard that MMO servers usually cap out at 2000 online players per server, could I reach this kind of value by using one thread per player.or the cpu would bottleneck too much?
My server is installed on Amazon EC2, so bandwidth wont be a problem, the performance will all depend on my implementation.
 
Second, how to detect when one client dropped the connection in TCP.
Let's say that one thread on the server is blocked on socket.Read() and the client just dropped the connection (for example, crashed ).
How should this be handled, does the blocking read() interrupts if the connection is dropped or it hangs there until the thread is killed by the main thread?
In the current implementation, since the sockets do not block, the server just keeps track of the timestamp of the last message received and drops the connection when too much time passes without new messages.


A thread per client is generally a horrible solution. An OS can pull this off but you have to consider the memory requirements of 2k threads, the cost of thread transitions and other things which in general will likely make this solution completely unusable. At the absolute worst you should learn how to use the select call to handle 32+ clients per thread in order to keep the thread counts down to something reasonable. At best on the target OS you didn't mention, find the appropriate API which is epoll for Linux, kevents for BSD and IOCP for Windows. Or, to save some time and effort, use Boost ASIO, libevent, libev or libuv to wrap up that side of things for you.

As to the error conditions on sockets, a dropped connection will return an error from recv. So, any wrapper around the low level sockets API should return the error and you need to catch them.

From the sound of things in general though. You have a LOT of learning to do before you are going to make a viable MMO server. I highly suggest you start with something a bit smaller such as just learning how to do a single connection properly which will teach you all the details you need to learn just on the sockets side. *THEN* scale up to a couple connections simultaneously to learn how they interact and finally at that point you can start thinking of your MMO server again. Of course the reality it that MMO servers are pretty huge beasts and realistically you will take a long time to learn all the bits and pieces which go into them.

Share this post


Link to post
Share on other sites

I know how to use sockets, at least at a reasonable level, as I said I've got a complete of the server already working, and the client is already finished.

The only problem is that now I have around 50 players online at the same time and the single thread solution I used for the server does not handle it well.

I am doing this in Windows, with Winsock directly.

Can you give a quick explanation of that Select call?

Share this post


Link to post
Share on other sites


I know how to use sockets, at least at a reasonable level

 

We obviously differ on what a "reasonable level" means as your questions are all "reasonably expected" that you know the answer before you tackle something this large.  I'm not trying to be a complete ass here, just stating that your questions are very basic networking 101 items you should have learned.  As to select, it was not really a seriously suggested solution, you should really be looking at IO completion ports on Windows for any real scaling.  Of course that is a massive pain in the ass to use correctly and won't be covered here.  At this point I suggest Google is your friend and you should look for "network api select" to find tutorials on that and/or "IO completion ports" to start the merry journey down the MS black hole of a crappy API's...

Share this post


Link to post
Share on other sites

Don't use windows for your "mmo server."

It's not unreasonable on an actual Windows Server, but I can guarantee you there are decent existing solutions and/or guides for Linux and its cousins.

Share this post


Link to post
Share on other sites

Also, when you start talking about large scale applications (MMO*), you probably should start studying distributed computing, load balancing, and IPC concepts in depth first before diving in. These are pretty advanced topics, and creating efficiently scaling systems is very difficult. It may also help to move from the mindset of one monolithic server process controlling the game to thinking in terms of multiple modular programs running in parallel to spread the work load.

Share this post


Link to post
Share on other sites

and of course did not scale properly.
The single threaded version just polled all player sockets constantly, and the response times were atrocious with more than 15 players online


What the others have said: If you can't even do 15 players on a single thread without lag, then you're doing something wrong.
EverQuest did 150 players per zone over ten years ago, on not only single-thread, but single-core, single-CPU servers.

Btw: Windows *can* be used for servers. Aforementioned EverQuest used it. Arena.net (Guild Wars, GW2) does it. Xbox Live! also does it, and is a pretty big online gaming service. :-) It's sometimes a bit more painful or more expensive than Linux for many use cases, but if you know Windows and don't know Linux, it may be worth it to stay on Windows.

Really, unless the simulation code itself can't keep up with a 30 Hz update rate, then a single-threaded networked server should be able to keep up with up to 64 players just fine using select(), and probably 1,000 players if using single-threaded I/O completion ports. The way to add threads, if on Windows, is to then use more worker threads for the I/O completion ports that you tie your sockets to. And here, you should use one thread per core, not one thread per user.

Finally: If anyone thinks this means that I'd prefer to write servers on Windows, the answer is a resounding "no" -- I'm most effective on Linux and other UNIX flavors for servers. But Windows is not a "no go," and we shouldn't automatically dismiss it "just because."

Share this post


Link to post
Share on other sites

I see, if everquest did it single threaded then my server should be also able to support more, I might be doing something wrong, or not getting enough bandwidth in EC2 (I'm using the free version for now, might be capped, I need to check).

I've heard about IO completion ports before and that is extremely difficult to use, so if linux would easier for me I might change to it. I dont know much about Linux though.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!