likerRr
@likerRr
front-end developer

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

Добрый день. Я не буду описывать реальную ситуацию, т.к. она довольно непроста, попробую рассказать суть, которой хочется добиться и собственно услышать ваши мнения по этому вопросу.

Итак, представьте ситуацию: есть игра, в которой игроки подключаются к комнате и ждут ее начала. Когда игра начинается (неважно, как она начинается, просто началась), каждый игрок об этом узнает посредством broadcast-а. Тут все хорошо. Далее у каждого игрока запускается таймер с интервалом в 1 секунду (грубо говоря продолжительность текущей игры). Каждую секунду каждый игрок генерирует число (в нашем общем случае пусть это будет какое-то random значение) и ему необходимо это число разослать всем участникам этой комнаты, а им в свою очередь надо получить это число в эту же секунду. Серверная часть написана на Node.js и Socket.io.

Например:
1) есть игрок1 и игрок2
2) началась игра
3) 1ая секунда игры: игрок1 отправил на сервер число 15, а игрок 2 - число 18
4) в эту же 1ую секунду игрок1 должен увидеть, что игрок2 отправил число 18, а игрок2 должен увидеть, что игрок1 отправил число 15

Проблема в том, что я не уверен, как правильно это реализовать, т.к. не знаю, успеют ли данные доходить до игроков за эту 1ую секунду, ведь им надо отправить свое число, а всем остальным получить это число за ту же секунду. Я вижу 2 варианта:
1) Игрок1 отправляет свое число на сервер. Складываем это число в массив, примерно такой: usersPoints[userId][second] = points. В эту же секунду игрок2 запрашивает данные из массива и уже смотрит, сколько очков у игрока1. Проблема: я не уверен, что данные от игрок1 успеют положиться в массива раньше, чем игрок2 их запросит.
2) Игрок1 отправляет свое число на сервер. Сервер броадкастит в комнату это число. Проблема: я не уверен, что число от игрока1 дойдет до сервера именно в ту секунду, когда оно нужно игроку2. Ну, возьмем к примеру медленный интернет. Получается, что по таймеру у игрока1 сработает событие "отправить число на сервер". Игрок2 в эту же секунду будет ждать число от игрок1, но т.к. у игрок1 медленный интернет, а таймер игрока2 его ждать не будет, то игрок2 может просто не дождаться этого числа.

Я тестировал 1ый вариант и результат был ожидаемый (мной), число то доходило (до всех остальных), то нет. Пробовал отправлять очки не каждую секунду, а каждые 990мс, а запрашивать каждую секунду, но тогда со временем (уже минуты через 2) они уже становятся не совсем актуальными.

Если вам не совсем понятно, зачем игрокам отправлять и получать числа, то давайте попробую объяснить в целом. Когда игра стартует каждую секунду каждый игрок своими действиями генерирует количество очков. Остальные игроки должны видеть его очки в эту секунду (а он видеть очки других игроков), чтобы сравнивать их со своими.

Я в отчаянии. Вроде и проблема совсем обычная, обмен актуальными данными в текущую секунду, а какой выбрать подход - не знаю. Отсюда и вопрос: каким наилучшим образом организовать обмен актуальными данными между игроками в течение одной секунды?
  • Вопрос задан
  • 2999 просмотров
Решения вопроса 1
pavel_salauyou
@pavel_salauyou
Symfony2 & Angular разработчик
непонятно зачем их запрашивать, сообщение в socket.io должно отправиться с сервера, а соединение ведь постоянное.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
saboteur_kiev
@saboteur_kiev
software engineer
Проектируйте игру таким образом, чтобы требования по частоте обмена трафиком между игроками не превышали разумный пинг.
Множество проектов загнулись, когда игра была критична к пингу, а из-за популярности и наплыва игроков, играть стало невозможно (тот же tetrisarena, где требовалось до нескольких раз в секунду обмен всего лишь между двумя участниками, начало загибаться, когда общий онлайн на сервере превысил несколько тысяч человек), видимо не успели развести игроков на несколько разных серверов, и на проект забили.

В то же время, средний пинг на который следует рассчиывать - до 20 мс. в идеале до 10 мс. Вот и посчитайте что и сколько раз можно передать за такой промежуток, умножьте на количество игроков и сравните с аплинком к вашему серверу, сколько игроков он потянет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы