2009-04-29 58 views
11

我一直在寻找一个很好的通用二进制网络协议定义框架,以提供一种方式来编写实时游戏服务器和客户端(想想World of Warcraft或Quake III)多种语言(例如用Objective-C和Cocoa编写的Java后端服务器和iPhone前端客户端)。可用游戏网络协议定义语言和代码生成

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

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

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

+0

这条语句的意思是:“不必绑定到某种RPC端点” – grieve 2009-05-26 19:30:40

+0

通过“不必绑定到某种类型的RPC端点”,我的意思是在服务器端,我不希望它只是能够接受我希望它能够启动反向的RPC请求向客户请求,并接收消息。 基本上我不想要一个RPC客户端/服务器设置,我想要一个客户端消息流和服务器消息流,其中消息是在某些IDL中定义的,可以为多种语言的客户端/服务器生成代码绑定。 – Dougnukem 2009-05-27 18:56:31

+0

我明白你现在在说什么。感谢澄清。 – grieve 2009-05-27 20:06:06

回答

14

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

  1. Google's Protocol Buffer - 但它缺乏的东西像发送/从给定的协议接收任意消息的支持。
  2. Apache Thrift - 一个有趣的选择,但它主要是面向对RPC,而不是普通的游戏客户端/服务器插槽类型的连接在客户端或服务器可以随时发送消息,而不仅仅是响应客户端RPC请求。
  3. Raknet Multiplayer - Raknet提供了完整的多人网络库(它是免费与在$ 25万的收入独立发展)

UPDATE:OculusVR收购RakNet和自由/开放源代码了。 U可以找到它的Github

  • Hessian Binary Web Service Protocol - 是一个HTTP Web服务二进制协议,它是非常适合于发送的二进制数据而不需要带附件的扩展协议。
  • Raknet提供一个良好的游戏/模拟面向多人库。

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

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

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

    0

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

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

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

    0

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

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

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

    0

    ASN.1符合“良好的通用二进制网络协议定义框架”的定义。它也通过ITU-T进行了标准化,所以现在有很多用于各种语言的现有工具和库。

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

    0

    为什么不直接实现UDP?你的问题大多提到你不想要的东西。什么进一步形​​式的弃权你想在UDP之上? 下载Quake III源代码并查看它们如何通过UDP构建游戏更新?

    IP协议被设计为以统一的方式支持多个设备/操作系统,这不是你要求的吗? 什么协议在大范围的系统中实现,嗯,IP也许?

    1

    如果你去写你自己的协议的路线,你可能需要阅读我张贴here答案。

    概括论述了什么,你应该考虑写一个协议时,并列出一些技巧的版本和维护向后和向前兼容性。

    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; 
    }; 
    

    这确实需要一些更多的基础设施..流,包基类,安全系列化功能..