【问题标题】:Which protocol to choose for a turn-based game server为回合制游戏服务器选择哪种协议
【发布时间】:2011-03-22 05:11:56
【问题描述】:

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

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

首先,我从我的选项列表中排除了 UDP,因为我需要一个可靠的协议,因为在极少数情况下,我确实需要发送一些无法放入一个数据包中的数据,并且我不想为合并数据包和类似的事情而烦恼东西,跟踪到达包裹的顺序和其他低级的东西。

所以问题是使用 TCP 还是 HTTP。

TCP 尝试 #1

从客户端到服务器的连接(反之亦然)一直处于打开状态。这样,当玩家移动时,服务器可以很容易地通知游戏中的其他玩家移动了哪一步。这种方法困扰我的主要问题是,是否建议或什至可以一直打开多达 1000 个连接和套接字?

TCP 尝试 #2

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

  1. 打开/关闭与客户端的连接很昂贵
  2. 通知游戏中其他玩家的方式,因为与他们的连接很可能已关闭。在这种情况下,他们每个人都应该“轮询”服务器以获取更新,比方说每隔一秒。

建立 TCP 套接字/连接的成本是多少?这是一项昂贵的操作,还是仅在几毫秒(或更短)内完成?

HTTP

  1. 如果有很多开销 我将发送一个新的 GET/POST 只是发送几个字节?
  2. 我可以保持 1000 个 HTTP 连接到 客户端同时使用,然后使用 AJAX 或类似的东西要减少 高架?在这种情况下,1000 同时连接构成 关于重大问题 带宽/性能?

我愿意接受任何形式的建议/建议。

【问题讨论】:

  • 关于#2:每次建立连接时您都必须对播放器进行身份验证...这也可能很慢!?
  • 客户端和服务器都是Java写的吗?
  • 有几个客户端,其中一个是Java,但我正在寻找一个通用的解决方案。

标签: java http tcp


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      服务器应该能够同时打开大约 20'000 个套接字。如果决定使用http,可以使用tomcat 6+或jetty 6+的新comet特性,否则每个请求都会分配一个线程。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

            建立 TCP 套接字是一项相当便宜的操作。事实上,一般的 HTTP 模型就是这样做的。永远不要让 HTTP 套接字持续打开。 Ajax 调用、HTTP 调用,这些都是为了尽快打开和关闭而设计的,以便处理下一个请求。

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

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

            这里唯一的速度问题是您的服务器软件实际执行轮询查询需要多长时间。建立和关闭套接字的开销与您编写的服务器端代码的开销无关。

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

                我建议,如果您正在使用相当小的 (

                • HTTP 等更高级别的协议 (XML),如果您不想处理比特和字节,则无需处理。

                • 构建了它的存在、大厅(带有 MUC)、pubsub 机制、用户管理/身份验证、聊天等。不胜枚举......

                • 不必担心自己编写可扩展的服务器。大多数 Jabber 服务器都支持插件。只需编写插件并让服务器为您扩展它;有点像 HTTP 服务器

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

                • 接近实时且相当可靠。

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-06-26
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-04-20
                  • 2010-11-02
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多