我有一个网络应用程序,作为一个接口,以异地服务器,运行一个非常长的任务。用户输入信息并点击submit,然后chrome等待响应,并在收到新网页时加载该网页。然而,取决于网络,用户的输入,任务可能需要相当长的时间,偶尔chrome会在数据返回之前加载一个“无数据接收页面”(尽管任务仍在运行)。
有没有办法在我的任务还在思考的时候放置一个临时页面,或者干脆强迫chrome继续等待呢?提前感谢
发布于 2013-08-08 23:54:39
虽然您可以更改服务器上的超时或其他技巧来尝试保持页面“活动”,但请记住,可能存在您无法控制的连接的其他部分,它们可能会使请求超时(例如浏览器的超时值,或者浏览器和服务器之间的任何代理,等等)。此外,如果任务需要更长的时间来完成(变得更高级,或者只是因为使用它的人更多而变得更慢),您可能需要不断增加超时值。
最后,这类问题通常通过更改您的体系结构来解决。
对长时间运行的任务使用单独的进程
视图在单独的进程中启动任务的运行,然后立即返回响应,而不是在handling视图中提交请求并运行任务。此响应可以将用户带到“请稍等,我们正在处理”页面。该页面可以使用众多推送技术中的一种来确定任务何时完成(长轮询、web套接字、服务器发送的事件、每N秒一次AJAX请求,或者最简单的:让页面每5秒重新加载一次)。
让您的Web请求“启动”单独的流程
无论如何,正如我所说的,处理请求的视图并不执行长时间的操作:它只是启动一个后台进程来完成任务。您可以自己创建这个后台进程调度(有关可能的想法,请查看this Flask snippet ),或者使用Celery或(RQ)等库。
一旦任务完成,您需要以某种方式通知用户。这将取决于您在上面选择的通知方法。对于简单的"ajax请求每N秒“,您需要创建一个视图来处理检查任务是否完成的AJAX请求。一种典型的方法是让长时间运行的任务,作为最后一步,对数据库进行一些更新。然后,检查状态的请求可以检查数据库的这一部分是否有更新。
利害得失
使用这种方法(而不是尝试将长时间运行的任务放入请求中)有几个好处:
1.)处理长时间运行的web请求是一件棘手的事情,因为有多个点可能会超时(除了浏览器和服务器)。使用这种方法,您的所有web请求都非常短,而且超时的可能性要小得多。
2.)Flask (和其他类似的框架)被设计为只支持一定数量的线程,这些线程可以响应web查询。假设它有8个线程:如果其中4个线程在处理长请求,那么只剩下4个请求来实际处理更典型的请求(比如用户获取他们的个人资料页面)。您的web服务器的一半可能会被不提供web内容的事情所占用!更糟糕的是,您可能会让所有8个线程都运行一个长进程,这意味着您的站点在其中一个线程完成之前完全无法响应web请求。
主要缺点:任务队列的建立和运行需要更多的设置工作,这确实会使整个系统变得稍微复杂一些。但是,对于在web上运行的长时间运行的任务,我强烈建议使用这种策略。
发布于 2013-08-08 21:41:57
我相信这是因为你的web服务器(大多数情况下是apache)的超时时间很小。尝试增加此数字
对于apache,请看一下timeout option
编辑:我不认为你可以在火狐的Chrome (see this topic on google forums even though it's really old)中设置这个时间,在about:config页面上,输入timeout,你会有一些你可以设置的选项。我对Internet Explorer一无所知。
发布于 2013-08-08 23:40:58
让我们假设:
如果获得了这些,我建议不要使用标准的HTML表单提交,而是使用submit按钮启动一个JavaScript函数来监督处理。它会发布一条“use be patient...this可能需要一小段时间”的消息,然后使用jQuery.ajax调用超时值很长的耗时较长的服务器。jQuery超时以毫秒为单位,因此60000 =60秒。如果超时时间超过此时间,请相应地增加指定的超时时间。我看过一些报告,并不是所有的客户端都允许超长的超时(例如,iOS上的Safari显然有60秒的限制)。但一般来说,这将为你提供一个平台来管理交互(与你的用户,与缓慢的服务器),而不是受制于简单的web表单提交。
这里有一些边缘情况需要考虑。web服务器超时可能确实需要向上调整(Apache默认为300秒,也就是5分钟,nginx小于IIRC)。对于您所看到的延迟,您的客户端超时(比如在iOS上)的最大值可能太低了。等。这些情况需要在服务器上进行调整,或者采用不同的交互策略。但是我要从AJAX管理的交互开始。
https://stackoverflow.com/questions/18127128
复制相似问题