可用的游戏网络协议定义语言和代码生成

时间:2009-04-29 22:43:08

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

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

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

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

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

9 个答案:

答案 0 :(得分:14)

我发现的网络协议框架如下:

  1. Google's Protocol Buffer - 但它不支持从您的协议发送/接收任意消息等内容。
  2. Apache Thrift - 一个有趣的选项,但它主要面向RPC而不是通用游戏客户端/服务器套接字类型连接,客户端或服务器可以随时发送消息,而不仅仅是响应客户端RPC请求
  3. Raknet Multiplayer - Raknet提供完整的多人网络图书馆(独立开发免费,收入低于25万美元)
  4. 更新:OculusVR现在收购了RakNet及其Free / OpenSource。你可以在Github

    找到它
    1. Hessian Binary Web Service Protocol - 是一个HTTP Web服务二进制协议,非常适合发送二进制数据,而无需使用附件扩展协议。
    2. Raknet提供了一个很好的面向游戏/模拟的多人游戏库。

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

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

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

答案 1 :(得分:2)

DIS

答案 2 :(得分:1)

如果你选择编写自己的协议,你可能想要阅读我发布的答案here

总之,它讨论了编写协议时应该考虑的内容,并列出了一些版本控制和维护向后兼容性的技巧。

答案 3 :(得分:1)

如果您真的关心多种平台和语言,请务必考虑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;
};

这确实需要更多基础设施..流,数据包基类,安全序列化功能..

答案 4 :(得分:0)

我想回应比尔K的建议。推出自己的协议并不难。

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

如果您希望在iPhone上使用测试服务器来对抗AsyncSocket,您可以查看Naga(对于Java服务器部分),它已经为基于分隔符的数据包和带有标头的数据包做好了准备。娜迦部分写了网络游戏。

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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