Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How game servers with Boost:Asio work asynchronously?

I am trying to create a game server, and currently, I am making it with threads. Every object( a player , monster ), has its own thread with while(1) cycle , in witch particular functions are performed.

And the server basically works like this:

main(){

//some initialization

while(1)
{
//reads clients packet
//directs packet info to a particular object
//object performs some functions
//then server returns result packet back to client
Sleep(1);
}

I have heard that is not efficient to make the server using threads like that, and I should consider to use Boost::Asio, and make the functions work asynchronously. But I don't know how then the server would work. I would be grateful if someone would explain how basically such servers work.

like image 979
Dainius Kreivys Avatar asked Feb 22 '23 03:02

Dainius Kreivys


1 Answers

Every object( a player , monster ), has its own thread. I have heard that is not efficient to make the server using threads like that

You are correct, this is not a scalable design. Consider a large game where you may have 10,000 objects or even a million. Such a design quickly falls apart when you require a thread per object. This is known as the C10K problem.

I should consider to use Boost::Asio, and make the functions work asynchronously. But I don't know how then the server would work. I would be grateful if someone would explain how basically such servers work.

You should start by following the Boost::Asio tutorials, and pay specific attention to the Asynchronous TCP daytime server. The concept of asynchronous programming compared to synchronous programming is not difficult after you understand that the flow of your program is inverted. From a high level, your game server will have an event loop that is driven by a boost::asio::io_service. Overly simplified, it will look like this

int
main()
{
    boost::asio::io_service io_service;
    // add some work to the io_service

    io_service.run(); // start event loop

    // should never get here
}

The callback handlers that are invoked from the event loop will chain operations together. That is, once your callback for reading data from a client is invoked, the handler will initiate another asynchronous operation.

The beauty of this design is that it decouples threading from concurrency. Consider a long running operation in your game server, such as reading data from a client. Using asynchronous methods, your game server does not need to wait for the operation to complete. It will be notified when the operation has completed on behalf of the kernel.

like image 188
Sam Miller Avatar answered Mar 07 '23 22:03

Sam Miller