0

我正在使用 GWT/Java 在 GAE 上编写游戏应用程序,并且遇到了服务器端持久数据的问题。玩家使用 RPC 轮询活动游戏和游戏状态,所有这些都存储在服务器上。有时客户端轮询无法找到我知道应该存在的游戏实例。这只发生在我部署到 google apppot 时,本地一切都很好。

我知道这可能与 apppot 是一项云服务有关,它可以在任何时候生成和使用我的 servlet 的新实例,并且现有数据不会在实例之间持久存在。

单个游戏只持续一两分钟,并且数据会迅速变化(每秒多次),那么确保对不同实例的 RPC 调用将使用相同的服务器端数据的最佳方法是什么?

我已经查看了 DataStore API,它似乎是像存储一样的数据库,我猜这对于我需要的东西来说太慢了。Memcache 也可以在任何时候刷新,所以没用。

我在这里想念什么?

4

3 回答 3

3

这里有两个问题:请求之间的持久数据和来自客户端的轮询数据。

  1. 当您有一个分布式 servlet 环境(例如 GAE)时,您不能向一个实例发出请求,将数据保存到内存并期望数据在其他实例上可用。这适用于 GAE 和任何其他有多个服务器的 servlet 环境。

    因此,您需要将数据保存到一些共享存储中:Datastore 成本高、持久、可靠且速度慢。Memcache 快速、免费,但不可靠。通常我们使用两者的组合。一些库甚至透明地结合了两者:NDBobjectify

    在 GAE 上,还有第三种选择来拥有半持久化的共享数据:后端。这些是永远在线的实例,您可以在其中控制启动/关闭。

  2. 数据轮询:如果有多个客户端在等待更新,最好不要使用轮询。轮询会发出很多不必要的请求(服务器上的数据没有改变),并且仍然会有最小的延迟(因为您每隔一段时间就会进行轮询)。您可以通过Channel API使用推送而不是轮询。甚至还有 GWT 库:gwt-gae-channelgwt-channel-api

于 2012-05-16T18:31:32.310 回答
1

简短的回答:您没有将游戏设计为在 App Engine 上运行。

您听起来好像已经回答了自己的问题。您了解数据不会跨实例持久化。在服务器端持久化数据的两种机制是 memcache 和数据存储,但您也了解它们的局限性。你需要围绕这个来构建你的游戏。

如果您没有使用 memcache 或数据存储,您是如何持久化数据的(我最好的猜测是您实际上并没有持久化它)。从模糊的细节来看,您尚未将游戏架构成能够跨多个实例运行,这对于在 App Engine 上运行的任何应用程序来说都是必不可少的。这是一个基本的设计原则,你不知道任何 HTTP 请求会命中哪个实例。您必须重新架构才能使用数据存储区 + 内存缓存。

如果你想使用单个服务器,你可以使用后端,它的行为就像单个服务器一样(如果你将它限制在一个实例中)。坦率地说,由于成本的原因,如果你走这条路,你最好选择亚马逊或 Rackspace。您还必须自己处理扩展问题 - 即,如果游戏在特定服务器实例上运行,您需要构建一种方式,以使玩游戏始终命中该实例。

于 2012-05-16T14:43:14.763 回答
0

请记住,您可以在没有 GAE 的情况下部署 GWT 应用程序,请参阅以下说明:

https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuideRPCDeployment

您可能想问自己:您的应用程序是否需要多个服务器实例或 GAE 特定功能?

如果是这样,那么我同意 Peter Knego 关于 memcache 等的回复。

如果没有,那么您可以通过选择不同的托管选项(GAE 除外)来解决您的问题。特别是让您只使用一个实例的方法。然后,您确实可以简单地管理服务器内存中的所有游戏数据,就像我了解您到目前为止所做的那样。

如果此解决方案适合您的目的,那么您需要做的就是找到合适的托管服务提供商。这很可能是一种基于云的 PaaS 产品,前提是它们允许您对服务器实例的数量进行硬性限制(与 GAE 不同),并且它可以低至一个。例如,据我了解,Heroku (当前)允许您这样做,并且显然它适用于 GWT 应用程序,根据此线程:

https://stackoverflow.com/a/8583493/2237986

请注意,上述解决方案涉及一些摆弄,我不知道您的需求足以提出强烈建议。对于您正在尝试做的事情,可能会有更简单和更好的解决方案。特别是,请查看针对高度时间关键的实时多人游戏进行优化的非基于云的托管选项和服务器架构。

希望这可以帮助!让我们随时了解您的进展。

于 2013-04-03T00:29:21.670 回答