Доступные языки определения сетевого протокола игры и генерация кода

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

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

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

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

Ответы

Ответ 1

Структуры сетевого протокола, которые я нашел, следующие:

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

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

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

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

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

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

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

Ответ 2

DIS

Ответ 3

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

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

Ответ 4

Если вы действительно обеспокоены несколькими платформами и языком, обязательно учтите проблемы 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;
};

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Ответ 7

ASN.1 соответствует определению "хорошая основа определения бинарного сетевого протокола общего назначения". Он также стандартизован ITU-T, поэтому существует множество существующих инструментов и библиотек для разных языков.

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

Ответ 8

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

Ответ 9

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

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