有没有一种不需要服务器端修改的轮询替代方案?

11

我正在尝试创建一个基于"ajax"的小型基础多人游戏。对象的坐标由PHP "handler"提供。通过使用ajax每200毫秒轮询这个handler.php文件。

由于没有必要在没有任何变化时进行轮询,我想知道是否有类似的方式可以不频繁地轮询并完成相同的工作。例如Comet,但我听说需要为Comet配置服务器端应用程序。这是一个共享网络服务器,所以我不能这样做。

也许可以避免handler.php文件在客户端不需要更改时返回响应,这种情况是否可能?但是,即使有些东西还没有发生变化,客户端仍然会无用地请求响应。基本上,只有在需要向客户端发送信息时(例如修改对象坐标)才应使用带宽和服务器资源。

6个回答

11

Comet通常用于这种情况,并且它可能是一个脆弱的设置,因为它不是特别常见的技术,所以很容易“搞砸”。话虽如此,现在比我上次尝试(约2年前)时有更多的资源可用。

我认为你不能像想象的那样让handler.php什么都不返回并停止执行:Web服务器将保持连接打开并阻止任何进一步的轮询,直到handler.php做些什么(终止或提供输出)。当它这样做时,你仍然要处理一个响应。

您可以尝试长轮询技术,其中您的AJAX允许非常长的超时时间(例如30秒),而handler.php则在没有响应的情况下旋转,直到它有需要报告的内容,然后才返回。(您需要确保旋转不会占用太多资源)。如果handler.php“过期”并且没有发生任何事情,请让其退出并让AJAX再次轮询。由于它仅每30秒发生一次,因此与大约每秒5次相比,这将是巨大的改进。这将使您的轮询最少化。

但这就是Comet的设计目的。


8
由于Ajax只提供客户端服务器请求模型(通常称为拉取而不是推送),因此从服务器获取数据的唯一方法是通过请求。然而,解决这个问题的一种常见技术是,当服务器有新数据时才响应。因此,客户端发出请求,服务器保留该请求直到发生某些事情,然后回复。这样就避免了频繁轮询,即使数据没有更改,您也只需要在客户端收到响应后发送新请求。
由于您正在使用PHP,一个简单的方法可能是让PHP代码在检查数据更改之间每次调用sleep命令200毫秒,然后在数据更改时将数据返回给客户端。
编辑:我还建议在请求上设置超时。因此,如果2秒钟内没有发生任何事情,则发送“无更改”消息。这样客户端就知道服务器仍在运行并处理其请求。

有趣 - 不过,如果在200毫秒内发生了变化怎么办?由于间隔时间太长,新的检查需要相对较长的时间才能完成,对吧?有什么方法可以解决这个问题,还是我误解了你的意思? - Tom

5
由于这是标记为“html5”:HTML5有<eventsource>WebSocket,但实际上实现方面仍处于将来时态。
Opera实现了一个名为<event-source>的旧版本的<eventsource>

2
EventSource规范自2009年以来已经发生了变化,http://dev.w3.org/html5/eventsource/,EventSource是标准化的comet。 - 4esn0k

4
这里有一个解决方案-使用SaaS彗星提供者,例如WebSync On-Demand。无需担心服务器资源,无论是共享托管还是不共享,因为所有内容都被卸载,并且您可以根据需要推送信息。
由于它是SaaS,它将与任何服务器语言配合使用。对于PHP,已经编写了一个发布器,随时可以使用。

我已经接受了它,但我不会使用它,因为它既不免费也不开源。 - Tom
如果您只有少量用户,您可以免费使用10个用户,而且永远不需要付费。但是我理解,如果这是一个个人项目,带有成本的解决方案并不总是可行的。 - Jerod Venema
1
@Tom,SaaS至少有硬件和维护成本,完全不考虑软件许可证。 - Anton

1

服务器必须参与此过程。请与托管提供商核实可用的模块。或尝试说服他们支持Comet。

也许您应该考虑使用小型虚拟专用服务器(VPS)来实现此目的。


1
关于长轮询建议的一件事:如果您在共享服务器上,此解决方案的可扩展性将受到限制,因为每个活动的长轮询都会保持连接(以及服务该连接的服务器端进程)处于活动状态。您的提供商很可能对您可以同时打开的连接数有限制(无论是政策定义还是实际情况),因此如果您有更多的会话/窗口同时播放,则会遇到瓶颈。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接