【问题标题】:Client notification, should I use an AJAX Push or Poll?客户端通知,我应该使用 AJAX 推送还是轮询?
【发布时间】:2010-09-18 04:55:35
【问题描述】:

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

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

实现推送场景并不难,所以我想我会在这里看到意见。

感谢您的帮助。

编辑: 我研究了一个简单的 AJAX 推送,并基于 Mike Purvis 的 article 实现了一个简单的演示。 初始版本的客户端负载相当低,约为 5k,预计会在相当长的一段时间内保持这种状态。


感谢大家的回复。我决定使用轮询解决方案,但将其全部包装在一个实用程序库中,这样如果他们以后想更改它就更容易了。

【问题讨论】:

标签: javascript ajax web-services server-push


【解决方案1】:

我会实施民意调查只是因为它听起来更容易编写,并且保持简单非常有价值。

【讨论】:

    【解决方案2】:

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

    如果用户正在浏览网站,那实际上是不是从服务器请求信息,该通知可以搭载?

    【讨论】:

      【解决方案3】:

      因为使用推送需要在您的服务器和每个客户端之间维护一个开放的 HTTP 连接,所以我也会选择轮询 - 这不仅会消耗大量服务器资源,而且还会显着正如 matt b 提到的那样,实现起来更棘手。

      我的轮询经验是,如果您在足够繁忙的站点上的轮询间隔足够频繁,您的网络服务器日志很快就会被轮询请求淹没。

      编辑(2017 年):我想说您现在的选择是在 websockets 和长轮询之间(在另一个答案中提到)。听起来长轮询可能是正确的选择,具体取决于问题提到不需要实时接收通知的方式,不频繁的轮询周期很容易实现,并且不应该对您的服务器造成很大负担. Websockets 很酷,是当今许多应用程序的绝佳选择,但在这种情况下听起来可能有点矫枉过正。

      【讨论】:

      • “不仅会消耗……”什么。投票还是推?没有说清楚。
      • 哇,这个答案是从 2008 年开始的。从那以后发生了很多变化。
      • @mmacaulay 在 2017 年,您现在会建议什么样的技术? ))
      【解决方案4】:

      我自己没试过,但有人说COMET works and is easier than you think。还有一个名为Juggernaut 的Ruby on Rails 插件,我听说它得到了高度评​​价。同样,我没有使用它,所以 YMMV,但我的理解是,与轮询相比,它需要的资源要少得多。我相信(有人可以确认吗?)COMET 是 MacRumorsLive.com 提供 WWDC Stevenotes 实时博客的方式。

      【讨论】:

        【解决方案5】:

        在不知道您将拥有多少客户的情况下,不可能说轮询是否会比推送更昂贵。我建议投票,因为:

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

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

        【讨论】:

          【解决方案6】:

          两者都有不同的要求并针对不同的场景。

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

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

          提示!尽量使检查池的页面快速而干净,这样它就不会在每个请求中消耗服务器中的大量资源。我通常做的是在内存中保留一个标志(例如在会话变量中),说明池是否为空......所以,只有当池不为空时,我才会在池中查看。当池为空时(大多数情况下),页面请求运行得非常快。

          【讨论】:

          • 嗯,很有趣。谢谢你的建议,我可能会试一试。
          【解决方案7】:

          一定要使用 push 它更酷。如果您只想要简单的通知,我会使用 StreamHub Push Server 之类的东西来为您完成繁重的工作。开发自己的 Ajax Push 功能是一条非常棘手和崎岖的道路——你必须让它在所有浏览器中工作,然后处理防火墙和代理,杀死保持连接等......为什么要重新发明轮子。此外,它的占用空间也同样低,不到 10K,因此如果您优先考虑,它应该适合。

          【讨论】:

          • 有时我想我一定是唯一一个喜欢创造轮子的人
          • 一件事就是享受它。另一件事是,当您可以使用现有的时,有时间和资源专门用于它:)
          • 是的,在很多项目中,我都会考虑从零开始编码可以学到多少东西。两周后,我还没有开始实际的项目。
          • 在个人项目中,我尽可能从头开始编写代码,至少对于我以前没有做过的事情。但是当时间很重要时,不要重新发明轮子,从别人那里购买(如果是 FOSS,则借用)。
          【解决方案8】:

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

          【讨论】:

            【解决方案9】:

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

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

            【讨论】:

            • 如果您查看推送链接,前提是它本质上是一个较长的轮询,可以将数据缓慢地回传给调用者,这实际上是长轮询,但可以在准备好模拟推送时立即发送数据。
            • 啊,不用担心 - 我只是没有在任何回复中看到它,我觉得很奇怪 :)
            • @Oddman 在接受的答案中描述的轮询和长轮询之间有区别吗?
            • @Serob_b 是的。轮询是一个即时请求,例如每秒、每 5 秒等等。长轮询意味着您保持连接打开并等待响应,可能长达一分钟。好处是性能之一 - 更少的请求访问您的服务器,具有更好的用户体验(用户将在一个可用时立即获得响应,而不是等待下一次轮询)
            猜你喜欢
            • 1970-01-01
            • 2021-12-07
            • 1970-01-01
            • 2012-03-04
            • 1970-01-01
            • 2014-08-28
            • 2012-09-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多