Я использую Node.js и Redis. Я пытаюсь придумать надежный способ автоматического сопоставления игроков. Существует соответствующий сервер, а затем несколько игровых серверов.
Вот что мне нужно, чтобы это произошло:
- Игрок отправляет запрос на присоединение с типом игры (маленький / средний и т. Д.)
- Соответствующий сервер добавляет игрока в текущий тип игры, который ожидает игроков
- Игровой сервер отправляет игроку идентификатор игры
В настоящее время я реализовал это следующим образом:
- Соответствующий сервер слушает игру: queue: small, используя BRPOP
- Проверяет, существует ли игра: queue: small: id = id
- Проверяет, есть ли игра: id: длина пользователя <= 6 (максимальное количество игроков)
- Добавляет игрока в игру: id: список пользователей, если он есть
- Если длина игры теперь равна 6, она удаляет игру: queue: small: id
Если соответствующий сервер находит игру: queue: small: id отсутствует, он делает следующее:
- Игра INCR: nextGameId
- Устанавливает game: queue: small: id для ранее созданного идентификатора
- Добавляет идентификатор игры в игру: очередь: ожидание
Игровые серверы ждут, используя BRPOP для новых игр. Когда они его получают, они ждут, пока в игре будет минимум 2 пользователя, затем запускают таймер. Если они не заполняются в это время, они начинают с пользователей, которые у них есть, и впоследствии удаляют game: queue: small: id (таким образом вынуждая сваха запрашивать новую игру).
Хотя мой метод работает, я не уверен, что он будет хорошо работать на производстве, и он кажется очень запутанным. Я вижу потенциал для следующих проблем:
- Игровой сервер падает после принятия идентификатора игры из списка ожидания, в результате чего пользователи добавляются в игру: id: пользователи, но с ними ничего не происходит (сам сбой не является проблемой, но пользователи продолжают добавляться в эту очередь игр. )
- Если пользователь отключается и игра не началась, игровой сервер удалит пользователя из игры: id: список пользователей. Пока он находится в процессе, сервер поиска совпадений может добавлять пользователя в список и думать, что игра заполнена, тем самым удаляя его из очереди.
Мои первые мысли состояли в том, чтобы перейти в единую очередь пользователей, ожидающих один тип игры. Тем не менее, это создает дополнительные проблемы:
- Если сервер, к которому подключаются пользователи, дает сбой, он не удалит пользователя из очереди, оставляя этого пользователя в игре, когда он не существует. Я мог бы использовать отсортированные наборы для хранения времени запроса и проведения опроса клиента до тех пор, пока не будет возвращен идентификатор игры, но это будет означать, что я понятия не имею, сколько времени этот клиент ждал, и поэтому не знаю, стоит ли запускать игру. с меньшим количеством пользователей.
- Не помещая пользователей в игру, они не могут ни видеть, к чему присоединились пользователи, ни общаться с ожидающими пользователями (так как для этого требуется идентификатор игры).
Ничто из того, как я это настроил, не кажется правильным, поэтому я надеялся, что кто-то сможет предложить несколько лучших предложений. Мне действительно нужно разделить игровые серверы и серверы сватовства, хотя бы для того, чтобы вырастить их по мере необходимости.