Я делаю многопользовательскую игру на основе веб-браузера. Я определил, что websockets – лучший способ обработки сообщений, учитывая его природу в реальном времени. Клиент использует холст HTML5, чтобы отобразить игру и веб-сайты для связи с хостом.
Я решил использовать PHP для размещения игры, поскольку, по-видимому, он предпочитает хостинг-провайдеров. Я раньше не использовал PHP, но делал подобные вещи с помощью websockets в Java, но в значительной степени полагался на многопоточность.
Я смотрел несколько руководств по php-сокетам с несколькими клиентами; но большинство из них делают такие вещи, как fork, от новых процессов для каждого клиента. Поскольку у меня будет постоянно запущенный игровой цикл, я не думаю, что это подходит.
То, что я пытаюсь достичь, является средством назначения портов каждому клиенту при их подключении, прослушивании новых клиентов, обмене данными с текущим списком клиентов и запуске игрового цикла.
Места, где мне нужна помощь:
Может ли кто-нибудь дать мне некоторые технические советы о том, как достичь этих целей? Я не думаю, что все это выглядит слишком много, чтобы спросить PHP, но исправьте меня, если я ошибаюсь!
Некоторое псевдокод того, что я идеально хотел бы достичь на стороне сервера. Ни одна из функций не должна блокироваться: клиенты Array;
while(gamerunning) { CheckForNewClients(); GetStatusFromClients(); DoGameUpdate(); SendGameStateToClients(); }
[Обновление] Для всех, кого это интересует, я создал специальное приложение, поддерживающее веб-сокеты (в частности, используя Java и библиотеку веб-сокетов TooTallNates), а не фактический веб-сервис, поскольку, похоже, он имеет больше смысла, хотя, кстати, кажется, что большинство веб-браузеров имеют поскольку в результате проблем с безопасностью возникли сетевые сокеты в корзине.
Я бы не предложил использовать PHP для этого типа приложений. PHP официально не поддерживает многопоточность и работает PHP-скрипт в течение неопределенного периода времени (например, на сервере) на самом деле не является рекламируемой функцией.
Конечно, вы могли бы попробовать сделать историю 🙂
(пожалуйста, поправьте меня, если я ошибаюсь)
Вам действительно нужно запустить демон PHP, чтобы сделать это эффективно (и ему НУЖНО быть PHP 5.3). Я написал довольно полный обзор использования PHP для процессов демона . Независимо от того, что вы выбрали, я бы предложил вам использовать основанную на событиях систему запуска цикла.
Я разработал базовую библиотеку RunLoop под названием LooPHP, которая, вероятно, может быть полезной, особенно если вы собираетесь иметь дело с *_select
. Я был бы более чем счастлив ответить на любой вопрос, который у вас есть об этом.
РЕДАКТИРОВАТЬ:
В системе, основанной на событиях, вы не просто в списке команд, вы реагируете на слушателя. Например…
Вместо того, чтобы делать:
while( 1 ) { ... /* listen, react */ } /* repeat */
Запуск циклов выполняется путем регистрации слушателя (сокетов и других генераторов событий async)
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
Вышеприведенный случай представляет собой очень простой 1 источник EventLoop и вручную добавляет временные функции (их можно добавить даже из вызова ReactClass
).
В приложении, в котором я работаю, мне нужно было иметь как асинхронный фид событий в бэкэнд (через сокет), так и затем иметь возможность вызывать функции произвольного смещения от исходного события (для клиентов с тайм-аутом и т. Д.).
Если вы хотите больше примеров, вы можете найти их в github .
Надеюсь, вы сочтете это полезным.