MMO Network Layer Architecture

Started by
15 comments, last by wodinoneeye 10 years, 6 months ago

Trying to do concurrency in C# is an exercise in frustration, especially on mono.


I don't quite understand this statement.

C#, the language, actually has a few useful features for concurrency (lock, async/await.)

The .NET system libraries have some *excellent* features for concurrency, especially with the later "Async" versions of I/O instead of the "Begin" versions. (The Begin versions are still better than Java, but do generate garbage per operation.)
I've found the mono implementation of the system libraries to be shoddy, though, just like the mono implementation of pretty much any other library feature. Perhaps this is what you're referring to?

The WinForms UI framework, by contrast, is not so great for concurrent and threaded operations. Luckily, most servers don't need to worry about this UI problem much.
enum Bool { True, False, FileNotFound };
Advertisement

I think you are really trying to "put the cart before the horse". If you're *really* making a MMO, then the funding you have for content-creation should mean that you can afford to hire some experts for the network parts.

On the other hand, if you're making a smaller online multiplayer game (which is fine, too!) then you really don't need to worry about "the C10k problem". Pretty much any approach will definitely work.

Personally I can't really see a situation where any amateur-developed game is likely to hit the limitations of networking, unless you've made some incredibly bad decisions on the protocol design - which is something you should really think about early on.

There are a lot of hard things about network game programming, and the things you've mentioned are not part of them.

Note that in .NET, proper use of the XxxAsync() functions actually solve the C10k problem for you.

At least with Microsoft's implementation -- I don't know about the mono implementation.

There may be other reasons not to use Microsoft servers, though.

enum Bool { True, False, FileNotFound };

I think you are really trying to "put the cart before the horse". If you're *really* making a MMO, then the funding you have for content-creation should mean that you can afford to hire some experts for the network parts.

On the other hand, if you're making a smaller online multiplayer game (which is fine, too!) then you really don't need to worry about "the C10k problem". Pretty much any approach will definitely work.

Personally I can't really see a situation where any amateur-developed game is likely to hit the limitations of networking, unless you've made some incredibly bad decisions on the protocol design - which is something you should really think about early on.

There are a lot of hard things about network game programming, and the things you've mentioned are not part of them.

It's a remake of an old game. It's not a FPS type of game, but a web based one.

I just thought it was an interesting read (the articles) and wanted to know if anyone had done any testing/experiments of how to develop a server with that method.

Note that in .NET, proper use of the XxxAsync() functions actually solve the C10k problem for you.

At least with Microsoft's implementation -- I don't know about the mono implementation.

There may be other reasons not to use Microsoft servers, though.

I found an implementation on codeproject which I'm using as a base for my server. So far performance seems ok.

I have implemented several high performance TCP/IP servers, which send/recv well over 50k messages/second. My last project which launched in may this year was "a play-along" type of app for a TV show. Without going into details it handles well above 50k msg/sec, on a single machine (a pretty standard 8-core VPS machine).

What hplus0603 is saying is correct, the *Async functions is the way you wanna go. Usually when you wanna look up tutorials or info on this, you should look for the name "SocketAsyncEventArgs" which is the managed wrapper for the completion call, MSDN reference here: http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx

A few important tips to achieve good scalability here is:

  • Pool your SocketAsyncEventArgs
  • Use a single, very large, byte[] which you split into chunks manually. The buffer which gets sent into the socket API for send/recv calls gets pinned by the GC, and if you have many small buffers a considerable amount of time will be spent pinning/unpinning memory (which is a relatively expensive op).
  • Don't do any heavy processing in the complete callback, instead just put the SocketAsyncEventArgs object on a queue and de-queue on another thread on the thread pool. ThreadPool threads and IOCPThreads are not the same thing, if you do a lot of processing immediately in the IOCPThread that the complete callback happens on, you will starve the system of IOCP threads and your performance will tank.

That's really all there is too it. Don't be afraid of context switches, I have never ever had problems with them. Like someone else said it sounds like a lot of your threading knowledge is from the early 2000's.

One hopes the use of the term 'threads' these days is starting to include 'fibers' (to alleviate the ugly penalties of thread switching and data locking schemes).

With so many cores and (cross machine) dispersed data/tasks, there is alot of waiting and trivial processing (complicated by time-out conditions) that seriously needs reduced overhead.

--------------------------------------------[size="1"]Ratings are Opinion, not Fact

This topic is closed to new replies.

Advertisement