为回合制游戏服务器选择哪种协议

时间:2010-07-28 15:00:30

标签: java http tcp

我正在为Java中的回合制游戏编写游戏服务器。 这些是事实:

  • 游戏的速度很慢,所以客户端需要每8秒发送一次数据,而且这些数据大部分时间只是一个小的增量更新(几十个字节),除了加入游戏或列出可用的游戏等。
  • 服务器必须支持大量的玩家,比方说1000,玩几百个游戏中的一个
  • 当玩家转弯时,必须通知同一游戏中的其他玩家移动。游戏中玩家的最大数量约为10

首先,我从我的选项列表中排除了UDP,因为我需要一个可靠的协议,因为在极少数情况下我真的需要发送一些不适合一个数据包的数据,我不想打扰合并数据包和类似的事情,跟踪到达的包裹的顺序和其他低级别的东西。

所以困境在于是使用TCP还是HTTP。

TCP尝试#1

始终打开从客户端到服务器的连接(反之亦然)。这样,当玩家进行移动时,服务器可以容易地通知游戏中的其他玩家进行了移动。使用这种方法困扰我的主要问题是,是否建议甚至可以连续打开1000个连接和套接字?

TCP尝试#2

我想到的替代方案是,用于在客户端的每个请求上建立单独的连接/套接字。客户端将打开连接,将一些小数据发送到服务器并关闭该连接。使用这种方法,我可以有一个固定大小的线程池,比方说10,并在每个线程中单独处理客户端的请求,这样任何时候最多可以打开10个connectinos / socket。但是这种方法有两件事困扰我:

  1. 打开/关闭与客户端的连接的昂贵费用
  2. 在游戏中通知其他玩家的方式,因为与他们的连接很可能是关闭的。在这种情况下,每个人都应该“轮询”服务器进行更新,让我们说每一秒。
  3. 建立TCP套接字/连接的成本是多少?这是一项昂贵的操作还是仅在几毫秒(或更短)内完成?

    HTTP

    1. 如果会有很多开销 我会发送一个新的GET / POST 只是发几个字节?
    2. 我可以保持1000个HTTP连接吗? 客户同时使用 AJAX或类似的东西减少 高架?在那种情况下,将1000 同时连接构成一个 有关的重大问题 带宽/性能?
    3. 我接受任何形式的建议/意见。

8 个答案:

答案 0 :(得分:5)

仅供参考:HTTP TCP。使用TCP的特定协议,即。 HTTP基于TCP,就像TCP基于IP等。所以你真的选择在HTTP over TCP或TCP上的自定义协议之间。你是对的,UDP在这里不太匹配。

如果您自己编写服务器,使用HTTP的许多好处都会消失。 HTTP的主要优点是已经有高度优化的服务器,因此您可以将其用作简单有效的RPC系统。但如果您自己编写服务器,那么您不太可能达到Apache之类的效率,因此您不得不问为什么您不会选择使用更简单的协议?此外,围绕HTTP的仅拉式特性进行攻击似乎是错误的方法。

考虑到这一点,我只是在TCP上使用更轻量级的协议。您可以更好地控制连接,并可以通知感兴趣的客户端更新,而无需轮询更改。您还可以丢失HTTP请求/响应开销,这在您的情况下大多是多余的。您可以使用相当简单的定制协议,可能基于XML或JSON,也可以使用现有的RPC方法之一。

答案 1 :(得分:3)

我看到你看到的是“低级别”。您是否尝试过使用更高级别的内容,例如http://code.google.com/p/kryonet/(也是为游戏开发)? (并发现可能性能不佳?)

我认为KryoNet提供的结果非常好,使用他们的API编程速度非常快。

答案 2 :(得分:1)

服务器应该能够同时打开大约20,000个插槽。如果您决定使用http,则可以使用tomcat 6+或jetty 6+的新彗星功能,否则将为每个请求分配一个线程。

答案 3 :(得分:1)

HTTP恕我直言。您将能够通过任何代理。身份验证可以简单完成,一次使用HTTP会话或cookie。

不要担心服务器功能 - 大多数现代服务器可以处理数千个并发客户端。

答案 4 :(得分:1)

您的“尝试#1”没问题 - 拥有1000个打开的连接没有任何问题(单个IRC服务器同时打开超过100,000个TCP连接的情况并不少见。)

(您可能会发现某些操作系统设置需要在接近该数字时进行调整 - 例如,UNIX通常具有默认的每进程打开文件限制,但它很容易更改)。

答案 5 :(得分:0)

建立TCP套接字是一种相当便宜的操作。实际上,一般的HTTP模型就是这样做。您不应该持续打开HTTP套接字。 Ajax调用,HTTP调用,这些调用旨在尽快打开和关闭,以便可以处理下一个请求。

我不明白为什么投票设计在这里不理想。当用户将游戏实例留回主游戏列表以获取当前状态时进行轮询。当用户在主游戏列表中时,每15秒左右轮询一次。确保服务器快速,快速地处理此轮询 - 如果可能的话,不到一毫秒。

许多Web服务器同时具有256个连接的硬限制,尽管最近我在某些服务器上看到了1024个连接。无论如何,你永远不应该接近这个限制。如果您的软件针对速度进行了优化,则不应该打开超过一毫秒或两秒的连接,并且甚至无法接近使用256个插槽所需的用户数。

此处唯一的速度问题是服务器软件实际执行轮询查询所需的时间。建立套接字并关闭它的开销与您编写的服务器端代码的开销无关。

答案 6 :(得分:0)

只需使用TCP套接字,每个客户端的一个持久连接,以及执行I / O的线程。线程开销不是太高(Linux默认为新堆栈分配48k,因此对于1k客户端需要48兆,Windows分配2k IIRC),您的代码将更加干净且易于遵循,并且您将自动 - 用CPU核心扩展。如果您担心防火墙,请调查HTTP CONNECT和HTML 5 WebSockets。

答案 7 :(得分:0)

我建议如果你使用相当小(<50K)的游戏数据包进行基于回合制的多人游戏,你应该考虑使用XMPP / Jabber。以下是我认为原因的一些原因

  • 像HTTP这样的高级协议(XML),如果你不愿意,你不必处理位和字节。

  • 建立存在,游说(使用MUC),pubsub机制,用户管理/身份验证,聊天等。列表继续......

  • 不必担心自己编写可伸缩服务器。大多数Jabber服务器都支持插件。只需编写插件,让服务器为您缩放;有点像HTTP服务器

  • XMPP是一种可扩展的协议。您可以将游戏数据作为聊天播放量的一部分。防火墙友好,大多数服务器支持BOSH

  • 接近实时且相当可靠。

  • 免费开源客户端(smack)和服务器(openfire) - 用Java编写