Доступные языки определения сетевого протокола игры и генерация кода - PullRequest
11 голосов
/ 30 апреля 2009

Я искал хорошую базовую платформу определения бинарного сетевого протокола, которая позволила бы писать игровые серверы и клиенты в реальном времени (например, World Of Warcraft или Quake III) на нескольких языках (например, Java-сервер и iPhone клиентский интерфейс, написанный на Objective-C и Cocoa).

Я хочу поддерживать клиенты Java Flash, клиенты iPhone и клиенты C # в Windows (и клиенты XNA в XBOX).

Я ищу способ эффективной отправки / получения сообщений через потоковое соединение сокетов TCP / IP или UDP. Я не ищу что-то, что может быть отправлено через HTTP-веб-сервис, например, JSON или XML-маршалы Objects. Хотя протокол двоичного веб-сервиса Гессиана является очень интересным решением

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

Ответы [ 9 ]

14 голосов
/ 07 мая 2009

Обнаруженные мной рамки сетевых протоколов:

  1. Буфер протокола Google - но в нем отсутствует поддержка таких вещей, как отправка / получение произвольных сообщений по заданному вами протоколу.
  2. Apache Thrift - интересный вариант, но он ориентирован в основном на RPC, а не на общие игровые соединения типа клиент-серверный сокет, где клиент или сервер могут отправлять сообщения в любое время, а не только в ответ на запрос RPC клиента.
  3. Raknet Multiplayer - Raknet предоставляет полную многопользовательскую сетевую библиотеку (это бесплатно для инди-разработки с доходом менее $ 250 тыс.)

ОБНОВЛЕНИЕ : OculusVR приобрел RakNet и его Free / OpenSource. Вы можете найти его на Github

  1. Hessian Binary Web Service Protocol - это двоичный протокол веб-службы HTTP, он хорошо подходит для отправки двоичных данных без необходимости расширять протокол с помощью вложений.

Raknet предоставляет хорошую многопользовательскую библиотеку, ориентированную на игру / симуляцию.

Похоже, что Apache Thrift и буферные протоколы Google являются простейшими подходами к использованию в архитектуре клиент / сервер игрового сетевого протокола.

Hessian отлично подойдет, если вы хотите создать игровой сервер на основе веб-интерфейса с Java или флеш-клиентом с использованием некоторой технологии push-сервера, такой как COMET . Гессиан может предложить действительно интересный способ поддержки игр в реальном времени в Интернете и даже иметь возможность размещать их в виртуальных веб-решениях, таких как Google App Engine или Amazon EC2.

Существует обсуждение использования различных структур определения протокола для игр и других целей:

2 голосов
/ 28 мая 2009
1 голос
/ 29 мая 2009

Если вы действительно беспокоитесь о разных платформах и языках, обязательно учтите endian проблемы. Бинарный протокол, разработанный для этого использования, должен использовать сетевой порядок байтов, поэтому ему нужны настраиваемые функции сериализации для каждого типа данных; вы не можете просто вслепую вставлять структуры C в сетевые буферы.

Распространенным решением этой проблемы в игровых компаниях является наличие языка или спецификации описания протокола в простом формате, таком как XML или python или lua, а затем генерация кода для каждого целевого языка, который генерирует классы пакетов как со структурой данных, так и с сериализацией , Эта спецификация может использовать систему типов, которая начинается с базовых типов, а затем расширяется и включает специфичные для игры типы с семантической информацией, перечислениями или более сложными структурами. Например, файл данных может выглядеть так:

Attack = {
  source = 'objectId',
  target = 'objectId',
  weapon = 'weapon::WEAP_MAIN',
  seed = 'int'
}

Это может генерировать код вроде:

#define PT_ATTACK 10002

class PacketAttack : public Packet {
  public:
    PacketAttack () : m_packetType(PacketAttack::s_packetType) {}

    ObjectId m_source;
    ObjectId m_target;
    WeaponType m_weapon;
    int m_seed;

   bool Write(Stream* outStream) {
       Packet::Write(outStream);
       outStream << m_source;
       outStream << m_target;
       outStream << m_weapon
       outStream << m_seed;
   }

   bool Read(Stream* inStream);

 static const int s_packetType;
};

Для этого требуется больше инфраструктуры. Потоки, базовые классы пакетов, функции безопасной сериализации.

1 голос
/ 26 мая 2009

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

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

0 голосов
/ 26 мая 2009

Почему бы не реализовать UDP напрямую? В вашем вопросе в основном упоминается, что вы не хотите .. Какую дополнительную форму абстракции do вы хотите использовать поверх UDP? Загрузите исходный код Quake III и посмотрите, как они создают обновления игры по UDP?

Протокол IP был разработан для одинаковой поддержки нескольких устройств / ОС, разве вы не об этом просили? Какой протокол имеет реализации в огромном диапазоне систем, хм, IP, может быть?

0 голосов
/ 23 мая 2009

Поскольку вы хотите использовать разные языки, а также потому, что вы хотите что-то чистое / маленькое, я предлагаю буферы протокола Google. Вам нужна прекомпиляционная часть для RPC, но я действительно считаю, что это лучший вариант, когда вы начинаете смешивать разные языки ... Вот ссылка: http://code.google.com/apis/protocolbuffers/docs/overview.html

0 голосов
/ 07 мая 2009

ASN.1 соответствует определению «хорошая структура определения бинарного сетевого протокола общего назначения». Он также стандартизирован МСЭ-Т, поэтому существует множество существующих инструментов и библиотек для различных языков.

Кодировка DER подходит для эффективной сетевой связи, кодировка XER - для удобочитаемого (и записываемого) постоянного хранилища.

0 голосов
/ 06 мая 2009

Я не согласен с "подходом с использованием простых строк с разделителями": вопрос в том, что именно принесет пользу? Начало писать и поддерживать больше кода? Единственными причинами, которые я мог видеть, было отсутствие поддержки инструмента (запись для какой-то нечетной платформы), или конкретные (очень) жесткие ограничения производительности или размера сообщения. Или иногда очень хочется написать формат - это нормально, но это должно быть явной причиной.

В зависимости от конкретных потребностей я бы предложил рассмотреть JSON, поскольку он может читать и писать произвольные сообщения; имеет хорошие связыватели объектов для Java (так же, как xml), легче для чтения, чем двоичные форматы, и достаточно «хорош» для многих случаев использования.

Если размер сообщения очень важен, Protobuf может работать хорошо - хотя его размер не всегда такой же маленький, как у альтернатив gzip (gzip + xml, gzip + json сжать очень хорошо), обычно он близок.

0 голосов
/ 30 апреля 2009

Я хочу повторить предложение Билла К. Нетрудно накатить собственный протокол.

Что касается iPhone, взгляните на AsyncSocket , который поддерживает встроенные TCP-пакеты на основе разделителя, и нетрудно создать решение, использующее заголовки пакетов.

Если вы хотите быстро запустить тестовый сервер для AsyncSocket на iPhone, вы можете посмотреть Naga (для части сервера java), в котором есть готовые компоненты как для пакетов на основе разделителя, так и для заголовки. Нага был частично написан с учетом сетевых игр.

...