11

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

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

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

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

4

9 回答 9

15

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

  1. Google 的协议缓冲区- 但它不支持从给定协议发送/接收任意消息之类的事情。
  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。

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

于 2009-05-06T22:50:42.943 回答
2

DIS

于 2009-05-28T17:56:09.663 回答
1

如果您确实走上了编写自己的协议的路线,您可能想阅读我在此处发布的答案。

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

于 2009-05-26T19:44:23.343 回答
1

如果您真的很关心多平台和多语言,请务必考虑字节序问题。为此目的设计的二进制协议必须使用网络字节顺序,因此它需要自定义每个数据类型的序列化函数;您不能只是盲目地将 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;
};

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

于 2009-05-29T16:46:29.220 回答
0

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

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

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

于 2009-04-29T23:03:11.007 回答
0

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

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

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

于 2009-05-06T18:34:04.930 回答
0

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

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

于 2009-05-06T20:43:40.893 回答
0

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

于 2009-05-23T14:57:21.160 回答
0

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

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

于 2009-05-26T19:38:36.490 回答