Пошаговая карточная игра клиент-сервер - Unicast (TCP) или Multicast (UDP)

8

В настоящее время я планирую создать проект карточной игры, в котором клиенты будут общаться с сервером поочередно и синхронно, используя сообщения, отправляемые через сокеты. У меня есть проблема, как справиться со следующим сценарием:

(Клиент по очереди и отправляет свое действие на сервер)

  1. Клиент отправляет сообщение, сообщающее серверу о своем ходу за ход (например, разыгрывает карту 5 из его руки, которую нужно положить на стол)

  2. Сервер получает сообщения и обновляет состояние игры (сервер будет хранить все состояние игры).

  3. Сервер перебирает список подключенных клиентов и отправляет сообщение об изменении их состояния

  4. Все клиенты обновляются для отображения состояния

Все это основано на использовании TCP, и, глядя на это сейчас, это выглядит как шаблон Observer. Причина, по которой это кажется мне проблемой, заключается в том, что это сообщение не похоже на двухточечное, как другие, поскольку я хочу отправить его всем клиентам, и не очень эффективно отправляет одно и то же сообщение в сюда.

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

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

Тем не менее, обратите внимание, что я не заинтересован в использовании промежуточного программного обеспечения, ориентированного на сообщения, в качестве решения (у меня есть опыт использования MOM, и я заинтересован в рассмотрении других вариантов, кроме MOM, если TCP-сокеты - плохая идея!).

LDM91
источник

Ответы:

11

Не оптимизируйте преждевременно. Будь проще. Использование TCP в этом случае нормально, и я не вижу проблем с вашей текущей схемой.

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

XiaoChuan Yu
источник
Спасибо за ваш ответ, это было ясно и, кажется, отвечает на все, что я просил.
LDM91
3

Даже многие крупные популярные MMO используют исключительно TCP. Он сделает все, что вам нужно, со всеми необходимыми вам характеристиками эффективности.

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

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

Решать все эти задачи не обязательно, но для этого требуется глубокое понимание сетей, протокола IP и способов решения этих проблем.

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

Я бы предложил вам прочитать следующую серию статей. Он не идеален и делает несколько очень сомнительных утверждений (начиная с бессмысленной фразы «никогда не используйте TCP в играх»), но его технические детали полезны для новых сетевых программистов: http://gafferongames.com/networking-for-game- программисты / УДФ-против-TCP /

Шон Миддледич
источник
1
Во введении к этой статье автор заявил: «Выбор, который вы делаете, полностью зависит от того, какую игру вы хотите подключить к сети. Поэтому с этого момента и для остальной части этой серии статей я предполагаю, что вы хотите к сетевой игре в жанре экшн. Вы знаете такие игры, как Halo, Battlefield 1942, Quake, Unreal, CounterStrke, Team Fortress и так далее. "
XiaoChuan Yu
Ах, я пропустил это, когда просмотрел его, чтобы убедиться, что он был настолько хорош, насколько я его помню. Мой плохой, извини.
Шон Мидлдич
-1 для «Если вы вообще заинтересованы в использовании UDP, ваша самая первая задача в основном состоит в том, чтобы переопределить TCP поверх UDP», это очень неправильно IMO. Гораздо полезнее узнать, что UDP действительно делает то, для чего выбирается UDP.
о0 '.
@Lohoris: Это бесполезно и даже не правильно. Вы ДОЛЖНЫ иметь возможность отправлять гарантированные сообщения в порядке, даже с UDP. Вы должны иметь возможность отправлять негарантированные сообщения в порядке. Вы должны иметь возможность отправлять гарантированные сообщения о выходе из строя. Проще всего начать с TCP-подобного поведения, потому что оно требует реализации всех необходимых функций и его проще всего тестировать, и даже само по себе оно все еще дает полезные функции, такие как более прямой контроль использования полосы пропускания и задержки.
Шон Мидлдитч
@seanmiddleditch неправильно. Нет ничего плохого в использовании UDP и TCP в одной игре, поэтому вам не нужно реализовывать гарантированную доставку по UDP.
о0 '.