Как игровые серверы с Boost: Asio работают асинхронно? - PullRequest
4 голосов
/ 15 марта 2012

Я пытаюсь создать игровой сервер, и в настоящее время я делаю это с потоками. Каждый объект (игрок, монстр) имеет собственный поток с циклом while (1), в котором выполняются определенные функции.

И сервер в основном работает так:

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);
}

Я слышал, что неэффективно заставить сервер использовать такие потоки, и я должен рассмотреть возможность использования Boost :: Asio и заставить функции работать асинхронно. Но я не знаю, как тогда будет работать сервер. Буду признателен, если кто-нибудь объяснит, как в основном работают такие серверы.

1 Ответ

5 голосов
/ 01 апреля 2012

Каждый объект (игрок, монстр) имеет свою нить. Я слышал, что неэффективно, чтобы сервер использовал потоки вот так

Вы правы, это не масштабируемый дизайн. Рассмотрим большую игру, в которой у вас может быть 10 000 объектов или даже миллион. Такой дизайн быстро разваливается, когда вам нужен поток на объект. Это известно как C10K проблема .

Я должен рассмотреть возможность использования Boost :: Asio и заставить функции работать асинхронно. Но я не знаю, как тогда будет работать сервер. Я был бы признателен, если бы кто-то объяснил, как в основном такие серверы работают.

Вы должны начать, следуя учебным пособиям Boost :: Asio , и обратить особое внимание на Асинхронный TCP дневной сервер . Концепция асинхронного программирования по сравнению с синхронным программированием несложна после того, как вы поймете, что поток вашей программы инвертирован. На высоком уровне ваш игровой сервер будет иметь цикл обработки событий, управляемый boost::asio::io_service. Слишком упрощенно, это будет выглядеть так

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
}

Обработчики обратного вызова, которые вызываются из цикла событий, объединяют операции вместе. То есть, как только ваш обратный вызов для чтения данных из клиента вызывается, обработчик инициирует другую асинхронную операцию.

Прелесть этого дизайна в том, что он отделяет потоки от параллелизма. Рассмотрим длительную операцию на игровом сервере, например, чтение данных с клиента. Используя асинхронные методы, вашему игровому серверу не нужно ждать завершения операции. Он будет уведомлен о завершении операции от имени ядра.

...