Как серверу своевременно передавать события игры клиенту?

Я разрабатываю некоторую онлайн игру по типу клиент-сервер. В моей голове столкнулись следующие мысли:

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

Почему токен? У меня есть требование, что сокет после каждого запроса может (и даже будет) закрываться. То есть идентификация клиента по открытому сокету для меня не вариант.

Но! Это игра. Вся невизуалика будет происходить на сервере, а вся визуалика - на клиенте. То есть все игровые события будут происходить на сервере, а отображать их своевременно должен клиент. Я предполагаю, что клиентов одновременно будет не один десяток, и каждый из них будет посылать множество своих собственных запросов. Так мне и события игры им нужно передать! А как сервер может сам установить соединение с клиентом, если знает о нем только токен? Вот тут я и осел на мель мыслей.

Все, что мне пришло в голову, так это добавить спам запрос от клиента, в ответ на который сервер должен сообщить ему о возникших событиях. Мне кажется это не самым рациональным решением. Есть ли другие подходы?


Ответы (2 шт):

Автор решения: S.H.

Уважаемый Shamus Rezol, поздравляю Вас, вы в "клубе"!

Вопрос про передачу событий с сервера на клиент - закономерно возникает при постепенном усложнении сценария взаимодействия клиента и сервера. То, что это вопрос возник у Вас - замечательно.

Рассмотрим два сценария. Первый - "браузерная игра"

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

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

То есть, архитектура Вашего решения становится такой: после авторизации клиент открыввет WS - соединение с сервером и ждёт.

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

С клиента на сервер передаются действия игрока. По этому же самому веб сокету.

Второй сценарий - когда мы не привязаны к браузеру.

В этом случае всё немного сложнее.

Вы хотите получить обновления состояния с сервера, не поддерживая с ним постоянного соединения. Теоретически, можно использовать UDP - просто рассылать UDP пакеты с обновлениями состояния. Тогда у Вас есть только одна проблема: клиенты могут "отваливаться": менять IP (клиент вошел в квартиру и переключился с сотовой сети на домашний WiFi), находиться за файерволами, котрые не пропускают UDP и т.п.

Тогда придётся "городить огород": сервре должен слать пакет "в любом случае", даже если ничего не изменилось, по таймауту (например, 5 секунд), а клиент, если он в течение таймута (например 10 секунд) не получил пакета - должен повторно сам стучаться на сервер.

Получается уже сложнее и не экономит трафик. Возможно, схема с постоянным соединением будет всё же проще

→ Ссылка
Автор решения: Pavel Mayorov

Ну, в теории сервер может запомнить IP-адрес клиента и подключиться к нему как клиент к серверу. Но в текущем интернете такой подход сломается о NAT и прочие брандмауэры и межсетевые экраны.

Поэтому нормальный вариант остаётся только один - сервер просто должен дождаться, пока клиент к нему присоединится и подтвердит свой токен.

→ Ссылка