Обычный веб-запрос живёт до ответа и на этом умирает. Игровому серверу такого мало: он обязан сам, ничего не дожидаясь, сообщить клиенту, что рядом появился монстр, что по игроку прошёл удар, что открылась дверь. Значит, соединение должно держаться постоянно — и за это приходится платить.

Что даёт постоянное соединение

Входящие соединения обслуживает CLI-демон: он держит открытые сокеты и разбирает всё, что шлют игроки. На PHP эту роль закрывает workerman.

WebSocket — это не отдельная сеть, а набор правил поверх TCP: как выглядят заголовки, чем разделяются пакеты, как проходит рукопожатие. Сам TCP даёт две вещи, ради которых всё и затевается: гарантию доставки и порядок — пакеты придут ровно в той последовательности, в какой ушли. А постоянное соединение снимает расходы на установку нового при каждом обмене.

Никто не мешает написать поверх TCP собственный протокол — та же библиотека это позволяет. WebSocket выигрывает тем, что его уже понимает браузер.

У HTTP есть keep-alive, который удерживает соединение открытым, но оно закроется через несколько секунд простоя. Пошаговой игре этого хватит, реальному времени — нет.

Чем за это платишь

Гарантия доставки стоит времени: на пакет идёт подтверждение о получении. Пакеты выстраиваются друг за другом, а не летят параллельно. И к полезным данным на каждом сообщении добавляются служебные заголовки.

Рядом есть второй базовый протокол — UDP. Накладных расходов меньше, данные идут сплошным потоком, доставка не гарантируется вовсе. Он оправдан там, где поток настолько плотный, что потерять часть пакетов дешевле, чем ждать подтверждения: так устроены шутеры вроде Counter-Strike. Мне важнее гарантия — в 2D MMO потерянный пакет с уроном или перемещением ломает картину мира у игрока.

Сколько это держит на PHP

Теоретическая пропускная способность TCP на одном порту упирается в числа, к практике отношения не имеющие. Интереснее замеры на живом фреймворке.

В этих тестах workerman занимает:

  • 1 место (с использованием php 8 и Jit пре компиляции php скриптов в некие "бинарники")

  • 2 место - его модификация с заменой Apache и Nginx на HTTP сервер написанный на PHP слушающий порт сервера (те работает и определяется PHP как CLI , без запуска fpm workers). Документация на Китайском , но механика следующая : Singleton'ы (грубо говоря закешированные экземпляры классов) всех контроллеров, вызывающиеся в onMessage() (метод срабатывающий когда на порт сервера приходят данные посланные клиентом из браузера) с параметрами которые пришли в запросе и увеличенный параметр keep-alive (те между браузером и сервером устанавливается постоянное TCP соединение которое дольше остается открытым чем в том же Apache где этот параметр ~10 секунд) - нам не очень актуален этот фреймворк тк мы не будем использовать HTTP

  • 3 и 8 место держат вариации с использование PostgreSql и без модификаций

В среднем — около 350 000 запросов в секунду. Рейтинг снят на HTTP, но включённый keep-alive заставляет сервер вести себя почти как WebSocket: соединения удерживаются.

Остаётся вопрос, много это или мало и сколько игроков получится держать онлайн. Упирается он уже не в сеть: узкое место — где лежит состояние мира и как быстро к нему обращаться.

Что было дальше

Тогда это был расчёт под будущий сервер. Сейчас на этой основе работает платформа: авторитарный сервер на PHP, открытый бесшовный мир, клиент на Unity и редактор, где игровая механика описывается текстом, а не правкой клиента. Куда это пришло — в последних частях серии.

История:

  1. Введение

  2. Масштабируемость и асинхронность

  3. WebSocket

  4. Redis

  5. LUA и JavaScript

  6. Выбор технологий, протокола и архитектурный шаблон Entity Component System

  7. Игровые локации (тайловые карты)

  8. Клиентская часть на Unity

  9. Игровые серверные механики

  10. Открытый бесшовный мир в 2D игре

  11. FPS, Ping, паузы между командами, интерполяция и экстраполяция

  12. Очереди и параллельное программирование на CPU

  13. Event-driven паттерн, JSON-RPC и почему не сервисная (SOA) архитектура

  14. Сетевая карта и задержка кадра (Latency frame) по RFC 2544 (1242)

  15. Создание сервера для онлайн ММО игр на PHP

  16. Готовое MVP сервиса 2D MMO RPG игр (realtime)

  17. Внедряю ИИ: механики из одного описания

  18. Конвейер контента для MMO: импорт анимации, экипировка и обновление игры без патчей

  19. Каталог ассетов и git: как командой вести игру в облаке

  20. Тесты для кода, который пишет ИИ: контракты вместо ассертов

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Нравится ли Вам как преподносится материал?
50%Да, все простыми словами и понятно12
41.67%Нет, нужно больше технического языка и подробностей10
8.33%Мне ничего не понятно из написанного2
Проголосовали 24 пользователя. Воздержались 11 пользователей.