【问题标题】:Available Game network protocol definition languages and code generation可用的游戏网络协议定义语言和代码生成
【发布时间】:2010-10-22 17:18:03
【问题描述】:

我一直在寻找一个好的通用二进制网络协议定义框架,以提供一种以多种语言(例如 Java 后端服务器和 iPhone)编写实时游戏服务器和客户端(想想魔兽世界或雷神之锤 III)的方法用 Objective-C 和 Cocoa 编写的前端客户端)。

我想支持 Windows 上的 Java Flash 客户端、iPhone 客户端和 C# 客户端(以及 XBOX 上的 XNA 客户端)。

我正在寻找一种通过 TCP/IP 或 UDP 套接字流连接有效发送/接收消息的方法。我不是在寻找可以通过 HTTP Web 服务发送的东西,比如 JSON 或 XML 编组对象。虽然 Hessian 的二进制 web 服务协议是一个非常有趣的解决方案

我想要一种网络协议格式和客户端/服务器基本实现,它允许客户端连接到服务器并在定义的协议中发送任何消息并在协议中接收任何消息,而无需绑定到某种 RPC 端点.我想要在我的协议传入和传出的任何消息的通用流。这样我就可以支持服务器每 100 毫秒向所有客户端发送游戏中各种实体的位置之类的东西。

【问题讨论】:

  • 这句话是什么意思:“无需绑定到某种 RPC 端点”
  • 通过“不必绑定到某种 RPC 端点”,我的意思是在服务器端我不希望它只能接受 RPC 请求我希望它能够启动向客户端反向请求,并接收消息。基本上我不想要一个 RPC 客户端/服务器设置,我想要一个客户端消息流和服务器消息流,其中消息在一些 IDL 中定义,可以为多种语言的客户端/服务器生成代码绑定。
  • 我明白你现在在说什么。感谢您的澄清。
  • 前段时间,我在 SO 上问了一个非常相关的问题,您可能想查看进一步的指示:stackoverflow.com/questions/644834/… 用于实验性协议设计/开发?

标签: xna network-protocols real-time protocol-buffers


【解决方案1】:

我找到的网络协议框架如下:

  1. Google's Protocol Buffer - 但它不支持从给定协议发送/接收任意消息等功能。
  2. Apache Thrift - 一个有趣的选项,但它主要面向 RPC 而不是通用游戏客户端/服务器套接字类型的连接,客户端或服务器可以随时发送消息,而不仅仅是响应客户端 RPC 请求。
  3. Raknet Multiplayer - Raknet 提供完整的多人网络库(对于收入低于 25 万美元的独立开发者来说是免费的)

更新:OculusVR 现在收购了 RakNet 及其免费/开源。你可以在Github找到它

  1. Hessian Binary Web Service Protocol - 是一种 HTTP Web 服务二进制协议,它非常适合发送二进制数据,无需使用附件扩展协议。

Raknet 提供了一个很好的面向游戏/模拟的多人游戏库。

Apache Thrift 和 Google 的协议缓冲区似乎是在游戏网络协议客户端/服务器架构中使用的最简单的方法。

如果您想使用某种类型的服务器推送技术(如COMET)创建一个带有 Java 或 Flash 客户端的基于 Web 的游戏服务器,Hessian 似乎非常适合。 Hessian 可能会提供一种非常有趣的方式来支持网络上的实时游戏,甚至能够将它们托管在虚拟机网络解决方案上,例如谷歌的 App 引擎或亚马逊的 EC2。

有一些关于将各种协议定义框架用于游戏和其他用途的讨论:

【讨论】:

  • 就我个人而言,我会先看看协议缓冲区,因为现在似乎支持很多语言。您不需要使用 RPC 来发送 ProtoBufs,因此只要您先指定长度(例如 length|protobuf|length|protobuf...),您就可以轻松地将它们通过套接字流式传输。唯一的缺点是所有消息都必须提前定义,这可能是件好事。
【解决方案2】:

DIS

【讨论】:

    【解决方案3】:

    如果您确实选择编写自己的协议,您可能需要阅读我发布的here 的答案。

    总的来说,它讨论了编写协议时应该考虑的问题,并列出了一些用于版本控制和保持向后和向前兼容性的技巧。

    【讨论】:

      【解决方案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】:

        我想响应 Bill K 的建议。推出自己的协议并不难。

        对于 iPhone 端,看看AsyncSocket,它支持内置基于分隔符的 TCP 数据包,构建使用数据包标头的解决方案并不难。

        如果你很快想在 iPhone 上拥有一个测试服务器来对抗 AsyncSocket,你可以查看Naga(用于 java 服务器部分),它已经为基于分隔符的数据包和带有标头的数据包做好了准备。 Naga 在编写时部分考虑了网络游戏。

        【讨论】:

          【解决方案6】:

          我不同意“用简单的分隔字符串滚动你的方法”:问题是,究竟有什么好处?开始编写和维护更多代码? 我能看到的唯一原因是缺乏工具支持(为一些奇怪的平台编写),或者特定(非常)硬性能或消息大小限制。 或者,有时,真的很想写一个格式——没关系,但它必须是一个明确的原因。

          根据具体需要,我建议考虑 JSON,因为它可以读取和写入任意消息;具有良好的 Java 对象绑定器(就像 xml),比二进制格式更易于阅读,并且对于许多用例来说“足够好”。

          如果消息大小非常重要,Protobuf 可以很好地工作——虽然它的大小并不总是像 gzip 替代品(gzip+xml、gzip+json 压缩得很好)那么小,但它通常很接近。

          【讨论】:

          • @StaxMan,我完全同意编写自己的自定义协议是浪费时间,并且在尝试支持多种语言或扩展它时只会造成维护噩梦。 JSON 和 gzip+json 可能是一个不错的选择,特别是对于编写 Web 服务,但我更多地考虑我不需要或不想要基于文本的格式(如 Web 服务)的情况,但在你' d 想要快速的二进制消息协议,例如构建游戏服务器(如魔兽世界或雷神之锤 III),在这些情况下,将 JSON 文本解析为原生对象/结构是令人望而却步的。
          【解决方案7】:

          ASN.1符合“良好的通用二进制网络协议定义框架”的定义。它也是由 ITU-T 标准化的,因此有很多针对各种语言的现有工具和库。

          DER 编码适用于高效的网络通信,XER 编码适用于人类可读(和可写)的永久存储。

          【讨论】:

            【解决方案8】:

            因为你想使用不同的语言,也因为你想要一些干净/小的东西,我建议谷歌的协议缓冲区。您需要 RPC 的预编译部分,但我真的认为这是您开始混合不同语言时的最佳选择。链接如下:http://code.google.com/apis/protocolbuffers/docs/overview.html

            【讨论】:

              【解决方案9】:

              为什么不直接实现UDP呢?您的问题主要提到了您不想要的内容。您希望在 UDP 之上进一步进行什么形式的抽象do? 下载 Quake III 源代码,看看他们如何通过 UDP 构建游戏更新?

              IP 协议旨在以统一的方式支持多种设备/操作系统,这不正是您所要求的吗? 什么协议在大量系统中实现,嗯,也许是 IP?

              【讨论】:

              • 我正在讨论的协议与 UDP 或 TCP 实现的低级传输协议并不完全相同。我说的是应用程序级协议。从我读到的关于 Quake III 网络模型 (tilion.org.uk/Games/Quake_3/Network_Protocol) 的内容中,它们实现了一个非常简单的游戏命令子集,以发送到每个客户端。通过网络接收这些消息的代码是在 C 客户端/服务器中编写的,我正在寻找一种方法来自动生成代码,这样我就可以使用相同的应用程序以 Java/Objective-c 等其他语言创建客户端/服务器协议。
              猜你喜欢
              • 1970-01-01
              • 2011-01-07
              • 1970-01-01
              • 1970-01-01
              • 2012-04-08
              • 1970-01-01
              • 2010-09-25
              • 2017-09-09
              • 1970-01-01
              相关资源
              最近更新 更多