PHP игровой сервер, несколько клиентов TCP? - PullRequest
10 голосов
/ 24 ноября 2010

Я делаю многопользовательскую игру на основе веб-браузера.Я определил, что веб-сокеты являются лучшим способом обработки сообщений, учитывая их характер в реальном времени.Клиент использует холст HTML5 для рендеринга игры и веб-сокеты для связи с хостом.

Я решил использовать PHP для хостинга игры, так как это кажется предпочтительным для хостинг-провайдеров.Я раньше не использовал PHP, но делал подобные вещи с веб-сокетами в Java, но в значительной степени полагался на многопоточность.

Я смотрел несколько уроков по php-сокетам с несколькими клиентами;но большинство из них делают такие вещи, как отключение новых процессов для каждого клиента.Так как у меня будет постоянно работающий игровой цикл, я не думаю, что это подходит.

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

Места, где мне нужна помощь:

  • Как найти и назначить порты новым клиентам, уведомитьклиент этого порта, и очистите его, когда они отключатся.
  • Как сделать выше, и все другие операции с сокетами, не блокируя игровой цикл.Было бы приемлемо принимать сообщения от клиентов частичными порциями и действовать только после полного сообщения.

Может кто-нибудь дать мне несколько технических советов о том, как достичь этих целей?Я не думаю, что все это выглядит слишком много, чтобы просить PHP, но поправьте меня, если я ошибаюсь!

Какой-то псевдокод того, чего я в идеале хотел бы достичь на стороне сервера.Ни одна из функций не должна блокировать: клиенты Array;

while(gamerunning)
{
    CheckForNewClients();
    GetStatusFromClients();
    DoGameUpdate();
    SendGameStateToClients();
}

[Update]. Для всех, кто заинтересовался, я создал специальное приложение, поддерживающее веб-сокеты (в частности, с использованием Java и библиотеки веб-сокетов 'TooTallNates'), а нереальный веб-сервис, как казалось, имеет больше смысла, хотя, кстати, кажется, что большинство веб-браузеров из-за проблем с безопасностью переместили веб-сокеты в корзину.

Ответы [ 2 ]

7 голосов
/ 24 ноября 2010

Вам действительно нужно запустить демон PHP, чтобы сделать это эффективно (и это ДОЛЖНО быть PHP 5.3).Я написал довольно полный обзор использования PHP для процессов-демонов .Что бы вы ни выбрали, я бы посоветовал вам использовать систему циклов выполнения, основанную на событиях.

Я разработал базовую библиотеку RunLoop под названием LooPHP , которая может быть полезной, особенно если вы собираетесьиметь дело с *_select.Я был бы более чем рад ответить на любой ваш вопрос по этому поводу.

РЕДАКТИРОВАТЬ:

В системе, основанной на событиях, вы не просто while список команд, вы реагируетеслушателю.Например ...

Вместо выполнения:

while( 1 ) {
    ... /* listen, react */
} /* repeat */

Запуск циклов выполняется путем регистрации прослушивателя (сокетов и других генераторов асинхронных событий)

class ReactClass { ... }

$loop = new LooPHP_EventLoop( new ReactClass );

//add one time event
$loop->addEvent( function() {
    print "This event was called 0.5 second after being added\n";
}, 0.5 /* in seconds */ );

//this creates a repeating event, this is called right away and repeats
$add_event = function() use ( $loop, &$add_event ) {
    print "This event is REPEATEDLY called 0.1 every second\n";
    $loop->addEvent( $add_event, 0.1 );
};
$add_event();

//start the loop processing, no events are processed until this is done
$loop->run(); //php doesn't leave this call until the daemon is done
exit(0); //cleanly exit

Вышеcase - это очень простой 1 исходный EventLoop и вручную добавленные временные функции (их можно добавлять даже из вызова ReactClass).

В приложении, в котором я работаю, мне нужно было иметь оба асинхронных событиявходить в бэкэнд (через сокет), а затем необходимо иметь возможность вызывать функции с произвольным смещением относительно исходного события (для клиентов с тайм-аутом и т. д.).

Если вы хотите больше примеров, выможете найти их в github .

Надеюсь, вы найдете это полезным.

5 голосов
/ 24 ноября 2010

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

Конечно, вы можете попробовать создать историю:)

(пожалуйста, поправьте меня, если я ошибаюсь)

...