7

I am currently rewriting the server side of a very old mmorpg, and I was looking for a good opensource network library to use with C/C++.

As the client already exists, I can't use any library that enforces some kind of packet structure or communication (as, for example, RakNet).

The server will use mainly UDP, on three different ports.

After searching on the internet, I found out about boost::asio and libuv.

boost::asio seems like a mature option, as I will already be using boost, but I read that their UDP implementation is a little poor, and that it can't achieve the maximum performance of a multicore processor because of some locks when using epoll.

libuv seems great, is event-driven, supported by a big project, but currently there is no project of this kind using it, so I'm in doubt about usign it.

What do you people think? Can I use libuv in a project like that, or will I have to go with boost::asio? I am open to other suggestions too (they need to be cross-platform, and I already discarded enet, libevent and libev).

RenatoUtsch
  • 1,449
  • 1
  • 13
  • 20
  • [liblacewing](http://lacewing-project.org) might also be a good fit for this (supports epoll, kqueue or IOCP on Windows). Disclosure: I'm the main developer. – James M Apr 29 '13 at 12:28
  • Cool project, I will look on it, but I am tempted to use asio, as I will already use boost. – RenatoUtsch Apr 30 '13 at 16:29
  • 2
    @RenatoUtsch Hi Renato, and one year later, what have you choosed ? Could you give us some returns on your experience ? Thanks – Jean Davy Jun 02 '14 at 15:43

2 Answers2

5

Either libuv or Boost.Asio should be fine. I have observed similar results between the libraries in both real-time and near-real-time applications.

If you do use Boost.Asio, be aware of:

  • How to minimize the amount of handler memory allocation.
  • io_service locking can be eliminated by providing a concurrency_hint of 1 to the io_service constructor. However, this will not prevent locking within the reactor.

From my experience with game development:

  • If the network capabilities are provided to the game code through either an interface or queue, then it is fairly trivial to swap between one event-based library to another event-based library, such as Boost.Asio and libuv.
  • The server architecture has far more of an impact than the network code itself. Both Boost.Asio and libuv provide IPC functionality that may be useful for multi-daemon server architectures.

While there is some overlap between the two libraries, it may be worthwhile to read this comparison.

Community
  • 1
  • 1
Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
  • But if I specify a `concurrency_hint` of 1, then io_service will run on only a single thread. How can I take advantage of multithreading then? And thanks for the comparison, it really helped a lot. – RenatoUtsch Apr 29 '13 at 15:49
  • You can use multiple `io_service` objects. This approach is similar to libuv, as libuv supports multiple event loops, but it does not support running the same loop from multiple threads. With Boost.Asio, if you do not set _concurrency_hint_, then multiple threads can safely service the event loop. – Tanner Sansbury Apr 29 '13 at 16:34
  • but not setting concurrency_hint will cause locking problems with the reactor. Well, then I will launch various io_service objects based on the number of cores of the processor. I was reading that asio's UDP implementation is not very good, is that true? If it makes difference, I will have to use libuv after all. Do you know anything about that? – RenatoUtsch Apr 29 '13 at 16:45
  • _"Very good"_ is subjective, but Boost.Asio's UDP sockets use the same service as its TCP sockets, and I have yet to have the socket service be a bottleneck. Older versions had some overhead, specifically with event registration within the reactor, but Boost.Asio has been through various performance optimizations throughout its development. While libuv will likely be faster, my experience with mmorpg development is that the difference between Boost.Asio and libuv is often negligible. It is often the server architecture that ultimately limits maximum performance. – Tanner Sansbury Apr 29 '13 at 19:17
  • Thanks for all the help, I will go with asio then, as I am already using boost. – RenatoUtsch Apr 30 '13 at 16:30
1

libevent is excellent and it surprises me that you have discarded it. ZeroMQ is pretty good but Windows support is slightly limited. RabbitMQ is being by a fiend of mine in SF.

Boost.asio is also very good. Since it seems that you are limited to c++, then libevent is what I am using and it should far outstrip other MMO titles on which I have worked in terms of network latency and responsive networking, but it does require tcp.

Mickey Kawick
  • 187
  • 1
  • 12
  • The problem of libevent (and libev) is that their windows support is not very good. Except that, it seems very good indeed. Then I found libuv, that was made as a "replacement" for libev on node.js, claiming to be faster and supporting windows well. I really am tempted to use it. Have you ever had any experience with it? – RenatoUtsch Apr 29 '13 at 09:35
  • And also, what does you mean when you said that "it does require tcp"? Can't I use only UDP with it? – RenatoUtsch Apr 29 '13 at 09:49
  • libevent seems great... I am using it here for about 2 months now and it is very responsive. The best support for libevent is tcp. However, there is some support... just not the stuff you'll need like packet ordering and keep alive. IOW, you will need to implement these just like you would in regular udp. Also, you might enjoy reading this link. http://stackoverflow.com/questions/11361208/high-performance-scalable-udp-servers – Mickey Kawick Apr 29 '13 at 22:26
  • Well, yeah, I don't have much of a choice as I am making a server for a closed-source client. Thanks for the help, I will go with asio. – RenatoUtsch Apr 30 '13 at 16:32