客户端通知,我应该使用AJAX推送还是轮询?

时间:2008-10-20 20:52:03

标签: javascript ajax web-services server-push

我正在开发一种简单的通知服务,用于向浏览网站的用户传递消息。通知不必实时发送,但如果它们比每5分钟更频繁地发生,则可能是更好的用户体验。发送到客户端和从客户端发送的数据不是很大,而且是检索数据的直接数据库查询。

在阅读有关该主题的其他对话时,似乎AJAX推送可能导致更高的服务器负载。由于我可以忍受更长的服务器延迟,因此有必要让服务器推送通知或简单地轮询。

实施推送方案并不困难,所以我想我会看到这里的意见。

感谢您的帮助。

编辑: 我已经研究了一个简单的AJAX Push,并在Mike Purvis的基础上实现了一个基于此article的简单演示。 对于初始版本,客户端负载相当低,大约为5k,并且预计将保持相当长的时间。


感谢大家的回复。我已决定使用轮询解决方案,但要将其全部包含在实用程序库中,以便以后更容易更改它。

9 个答案:

答案 0 :(得分:12)

我很惊讶这里没有提到长轮询。长轮询意味着保持打开连接的时间更长(例如30-60秒),一旦关闭,再次重新打开它,只需让插座/连接听取响应。这导致更少的连接(但更长的连接),并且意味着响应几乎是立即的(一些可能必须等待新的轮询连接)。我想补充一点,结合NodeJS等技术,这将产生一个非常有效且资源轻的解决方案,在所有主流浏览器和版本中100%浏览器兼容,并且不需要任何其他技术,如Comet或闪光灯。

我意识到这是一个老问题,但认为提供这些信息可能仍然有用:)

答案 1 :(得分:10)

绝对使用push更冷。如果您只是想要简单的通知,我会使用类似StreamHub Push Server之类的东西来为您做繁重的工作。开发自己的Ajax Push功能是一个非常棘手和艰难的道路 - 你必须让它在所有浏览器中工作,然后处理防火墙和代理,杀死保持连接等...为什么重新发明轮子。此外,它具有类似的低足迹,小于10K,因此如果这是您的优先考虑,它应该适合。

答案 2 :(得分:7)

两者都有不同的要求,并针对不同的情况。

如果您需要实时更新,就像在线聊天一样,推送是必须的。

但是,如果刷新周期很长,就像你的情况一样(5分钟),那么pool就是合适的解决方案。在这种情况下,推送将需要来自客户端和服务器的大量资源。

提示!尝试快速清理检查池的页面,因此在每个请求中不会消耗服务器中的大量资源。我通常做的是在内存中保留一个标志(比如在一个会话变量中),该标志表示池是否为空......所以,我只在不是空的情况下才在池中查看havy。当池空时(大多数情况下),页面请求运行得非常快。

答案 3 :(得分:5)

因为使用推送需要在服务器和每个客户端之间维护一个开放的HTTP连接,所以我也会进行轮询 - 这不仅会占用大量的服务器资源,而且还会显着增加像matt提到的那样实施起来比较棘手。

我对轮询的经验是,如果您在足够忙碌的站点上有足够频繁的轮询间隔,那么您的Web服务器日志可能会很快地被轮询请求充斥。

编辑(2017):我说你的选择现在是在websockets和长轮询之间(在另一个答案中提到)。听起来像长轮询可能是正确的选择,基于问题提到不需要实时接收通知的方式,不频繁的轮询期很容易实现,不应该对你的服务器非常负担。 。如今,Websockets非常酷,是许多应用程序的绝佳选择,但在这种情况下,这听起来似乎有点过头了。

答案 4 :(得分:3)

我会实施民意调查,因为它听起来更简单,保持简单非常有价值。

答案 5 :(得分:1)

不确定你是否看过那里的一些COMET实现(这就是你所说的AJAX推送)。

如果用户正在浏览网站,那么实际上是否会从服务器请求此通知可以背负的信息?

答案 6 :(得分:1)

我自己没有尝试过,但有些人说COMET works and is easier than you think。还有一个名为Juggernaut的Ruby on Rails插件,我听说过这个插件。再说一次,我没有使用它,所以YMMV,但我的理解是它与轮询相比需要的资源要少得多。我相信(有人可以证实吗?)COMET是MacRumorsLive.com提供WWDC Stevenotes现场博客的方式。

答案 7 :(得分:1)

在不知道你会拥有多少客户的情况下,不可能说投票是否会更加昂贵。我建议投票,因为:

  • 听起来您想每分钟更新一次数据。除非通知能够以比这更快的速度到达,否则推送意味着您保持HTTP连接打开,但看到的活动很少。
  • 轮询是建立在现有HTTP约定之上的,因此任何与Web浏览器对话的服务器都已准备好响应普通的Ajax请求。基于Comet或Flash插座的解决方案有不同的要求;你需要服务器端的cometd和服务器端推送的客户端库。

因此,如果您需要一些重要的东西来管理大量数据和大量客户端,我建议使用Comet。但情况似乎并非如此。

答案 8 :(得分:1)

现在有一个服务http://pusherapp.com试图一劳永逸地解决这个问题。可能值得一试。 (免责声明:我与他们无关)。