13

我正在开发一个 Web 应用程序,该应用程序将任务提交给主/工作系统,该系统将任务分配给一系列工作实例中的任何一个。工作队列主机作为单独的进程运行(完全在单独的机器上),任务通过 HTTP/REST 请求提交给主机。将任务提交到工作队列后,客户端应用程序可以提交另一个 HTTP 请求以获取有关任务的状态信息。

对于我的 Web 应用程序,我希望它提供某种进度条视图,让用户可以了解任务处理的进度。实现这一点的明显方法是使用 AJAX 进度表小部件,该小部件定期轮询工作队列以了解已提交任务的状态。我的问题是,有没有更好的方法可以在没有频繁轮询的情况下实现这一点?

我考虑过让客户端 Web 应用程序打开一个服务器套接字,它可以在该套接字上侦听来自工作主管的通知。我的另一个类似想法是使用 XMPP 或类似的协议来进行状态通知。(当然,master/worker 系统需要更新以提供通知,但我拥有这方面的代码,因此可以自己进行任何必要的更新。)

关于设置这样的通知系统的最佳方式有什么想法吗?所涉及的额外努力是否值得,或者简单的轮询解决方案是否可行?

4

7 回答 7

11

轮询

客户端不断轮询服务器以获取响应的状态。

优点

  • 真正的 RESTful 意味着可缓存和可扩展。

缺点

  • 如果您不想过多地轮询服务器,则不是最佳响应能力。

持续连接

在响应完成之前,服务器不会关闭其与客户端的 HTTP 连接。服务器可以使用 HTTP 多部分通过此连接发送中间状态。

Comet是实现这种行为的最著名的框架。

优点

  • 最佳响应能力,来自服务器的几乎实时通知。

缺点

  • 连接限制在 Web 服务器上受到限制,保持连接打开时间过长可能会加载您的服务器,最坏的情况是使服务器受到拒绝服务攻击。

客户端作为服务器

使服务器发布状态更新和对客户端的响应,就好像它是另一个 RESTful 应用程序一样。

优点

  • 最棒的是,无论是在服务器端还是在客户端,都不会浪费任何资源来等待响应。

缺点

  • 您需要在客户端上有完整的 HTTP 服务器和 Web 应用程序堆栈
  • 具有默认“根本没有传入连接”的防火墙和路由器将成为障碍。

随意编辑以添加您的想法或新方法!

于 2009-06-25T14:01:10.440 回答
6

我想这取决于几个因素

  • 反馈的准确程度(1%、5%、50%)
    准确的反馈值得追求某种进度条和彗星式推送。如果你只能说“忙……等一下……快到了……完成了”,那么一个简单的 ajax“我们到了吗”民意调查肯定更容易编码。
  • 客户必须在多长时间内看到 Done 消息
  • 每项任务需要多长时间(1 秒、10 秒、10 分钟)
    1 秒有点没有意义。10秒就值得了。10 分钟意味着你最好建议用户去喝咖啡休息时间:-)
  • 会有多少并发请求
    除非你有一个“特殊的”服务器,否则实时推送式系统往往会吃掉连接,你很快就会被刷爆。不得不为花哨的进度条投入更多的网络服务器可能会损害预算。

我在871184上有一些示例代码,显示了一个手卷的“永远框架”,看起来效果很好。我开发的项目并没有那么辛苦,操作需要几秒钟,我们可以给出非常准确的百分比。该代码使用 asp.net 和 jquery,但一般技术适用于任何服务器和 javascript 框架。

编辑正如John所指出的,状态报告可能不是 RESTful 服务的工作。但是没有什么说您不能在客户端上打开一个 iframe,该 iframe 挂钩到轮询服务的服务器上的一个页面。理论上说服务器和服务至少会更接近彼此:-)

于 2009-06-25T13:47:59.267 回答
2

看看彗星。您向服务器发出单个请求,服务器会阻塞并保持连接打开,直到状态发生更新。一旦发生这种情况,就会发送并提交响应。浏览器收到此响应,处理它并立即重新请求相同的 URL。效果是将事件推送到浏览器。有利有弊,它可能不适用于所有用例,但会提供最及时的状态更新。

于 2009-06-25T13:32:32.557 回答
1

我的意见是坚持使用轮询解决方案,但您可能会对这篇关于HTTP 推送技术的 Wikipedia 文章感兴趣。

于 2009-06-25T13:26:06.253 回答
1

REST 依赖于 HTTP,它是一种请求/响应协议。我认为您不会获得一个纯 HTTP 服务器以状态回叫客户端。

此外,状态报告不是服务的工作。由客户决定何时或是否需要报告状态。

于 2009-06-25T13:27:12.880 回答
1

我使用的一种方法是:

  1. 当作业发布到服务器时,服务器会返回一个pubnub-channel id(也可以使用 Google 的 PUB-SUB 服务)。
  2. 浏览器上的客户端订阅该频道并开始侦听消息。
  3. 工作人员/任务服务器在该pubnub 频道上发布状态以更新进度。
  4. 在订阅的 pubnub 频道上接收消息时,客户端会更新 Web UI。
于 2020-09-24T04:14:09.440 回答
0

您也可以使用自刷新 iframe,但 AJAX 调用要好得多。我不认为有任何其他方式。

PS:如果您从客户端打开一个套接字,那不会有太大变化 - PHP 浏览器会将页面显示为仍在“加载”,这对用户不是很友好。(假设您之前会推送或刷新缓冲区以显示其他内容)

于 2009-06-25T13:24:24.477 回答