AJAX:如何在Web应用程序中获取进度反馈,并避免长时间请求超时?

这是一个一般设计问题,关于如何制作一个Web应用程序,它将接收大量上传的数据,处理它并返回结果,所有这些都没有可怕的旋转沙滩球5分钟或可能的HTTP超时。

这是要求:

  • 制作一个Web表单,您可以在其中上传包含URL列表的CSV文件
  • 当用户单击“提交”时,服务器将提取该文件,并检查每个URL以查看其是否存活,以及该页面的标题标记是什么。
  • 结果是一个可下载的CSV文件,其中包含URL和结果HTTP代码
  • 输入CSV可能非常大(> 100000行),因此获取过程可能需要5-30分钟。

到目前为止,我的解决方案是在客户端站点上有一个旋转的javascript循环,它每秒查询服务器以确定作业的整体进度。 这对我来说似乎很糟糕,我很犹豫是否认为这是最好的解决方案。

我正在使用perl,模板工具包和jquery,但任何使用任何Web技术的解决方案都是可以接受的。

编辑:可能解决方案的一个例子就是这个问题: 如何实现基本的“长轮询”?

您可以使用AJAX执行此操作,但您可以通过类似COMET的实现获得更好的实时结果。 我相信COMET实现是专门设计来解决一些超时限制但我没有使用任何所以我不能提供直接指南。

无论哪种方式,我的建议是一旦到达服务器就将工作交给另一个进程。

我已经为这种性质的批量任务开发了许多不同的解决方案,而我最喜欢的是将批量工作交给另一个流程。 在这样的系统中,上传页面将工作交给单独的处理器并立即返回用户监视该过程的指令。

批处理器可以通过以下几种方式实现:

  • 从IO分叉并分离子项以完成批处理。 父完成Web请求。
  • 将上传内容保存到处理队列(例如:文件系统上的文件,数据库中的记录),让Web服务器通知外部处理器 – 自定义守护程序或现成的调度程序,如“at”for * nix系统。

然后,您可以为用户提供多种方法来监控该过程:

  • 上载确认页面包含批处理过程的同步实时监视器(通过COMET或Flash)。 完成后,确认页面可以指导用户下载。
  • 像上面一样,但监视器不是活动的,而是通过AJAX或页面元刷新使用定期轮询
  • 队列监视器页面,显示它们已运行的任何批处理的状态。

批处理器可以通过多种方法传达它的状态:

  • 更新数据库中的记录
  • 生成处理日志
  • 使用命名管道

将代码交给另一个进程有很多好处:

  • 当用户意外停止浏览器时,该过程将继续。
  • 使用外部进程会强制您以允许您分离监视器并随时重新连接的方式传达批处理状态。 例如:当用户在流程完成之前意外导航离开页面时。
  • 如果您决定在低网络流量时间内分散批处理,则更容易实施批量限制和延期。
  • 您不必担心Web超时(客户端或服务器端)。
  • 您可以重新启动Web服务器,而无需担心是否正在中断批处理过程。

最简单的是批处理甚至流式处理作业。 如果您将其视为您页面上的数据表。 如果表有> 100000条记录,您只需一次请求所有记录。 我会这样做:

  1. 发送下载文件的请求。

  2. 发送处理100( 任意数量 )记录的请求。

    一个。 流程记录。

    湾 保存到临时csv文件。

    C。 回复完整 / 未完成过程的状态。

    d。 如果状态未完成,请重复步骤二。

您提到客户端不可信任,因此我建议(在客户端)每X个记录预解析文件,为每个记录子集附加校验和,然后允许客户端通过固定数量的连接上传代理,以便您可以更准确地监控进度。