node.js архитектура сервера многопользовательской игры

#architecture #node.js

#архитектура #node.js

Вопрос:

Допустим, вы создаете сервер для техасского холдема. У нас есть единственное лобби и несколько комнат, в которых проходят игровые сессии. На каком уровне вы разделяете комнаты?

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

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

Есть мысли? Имеет ли смысл «мультиплексировать» сервер с одним узлом для управления несколькими сеансами в игровой комнате?

Комментарии:

1. Лично у меня был бы единый сервер, управляющий всеми вещами. Я бы хотел, чтобы каждый входил по пути, например / rooms / 123, а затем обрабатывал все запросы одним и тем же кодом. Как именно вы планируете сбой игры? На что это похоже на ваш взгляд? Что это влечет за собой?

Ответ №1:

Технически, вам не нужно прослушивать отдельные порты для каждой комнаты. Это возможно, потому что ОС поддерживает родительские и дочерние процессы, совместно использующие один и тот же дескриптор сокета (файла). Для достижения этой цели вы можете использовать модуль узла WebWorker. Благодаря этой архитектуре вы автоматически получаете модуль балансировки нагрузки, который может распределять входящие подключения к различным дочерним процессам с помощью планировщика процессов операционной системы.

Однако в вашей системе самая сложная часть заключается в том, как совместно использовать общие данные между этими процессами, поскольку у них есть свои собственные области памяти. К счастью, есть несколько способов поделиться этими данными (онлайн-сеансы, комнаты, таблица результатов …), Но они могут быть довольно сложными. Один из способов — позволить дочерним процессам взаимодействовать с ведущим через IPC (сокет), а другой способ — использовать область общей памяти (база данных, memcached …), к которой каждый может получить доступ «на лету».

Я бы рекомендовал вам сначала построить свою систему, используя архитектуру процесса с одним узлом (если вы собираетесь использовать websocket, вы уже можете обрабатывать довольно большое количество одновременных подключений), затем, когда вам нужно расширить свою систему, используйте архитектуру webworker. Более того, миграция не займет много времени, если вы уже используете общее место для хранения / извлечения данных (база данных, memcached, хранилище ключей redis …).

Ответ №2:

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