【问题标题】:Python hold on the HTTP connection before sending files?Python 在发送文件之前保持 HTTP 连接?
【发布时间】:2015-03-21 08:19:13
【问题描述】:

问题

这个问题困扰了我很久。我正在处理一个 Web API,它提供了通过某些特定条件查询数据库、取回合格数据并生成 .xls 文件以供下载的功能。

但是数据量确实很大,所以生成.xls文件会比较耗时。 这可能会导致 HTTP 超时。我曾经创建一个生成器来逐行生成由 .csv 格式的记录。它在性能方面运行良好(我的意思是快速生成和下载),但是有一些副作用。正如我在前两个问题中提到的:

问题

经过深思熟虑,我最终决定在服务器端生成整个.xls文件,然后提供下载。但是在生成 .xls 文件的过程中如何维护 http 连接呢?

【问题讨论】:

    标签: python http web flask


    【解决方案1】:

    “如何在生成 .xls 文件期间保持 http 连接?”

    简单的答案:你不能。至少你不能保证一个简单的 HTTP GET 请求(和底层的 TCP 连接)可靠地工作。根据客户端的具体情况和客户端所在的网络,您的用户可能经常会遇到错误(您的应用程序无法处理的连接超时)。

    所以,正确的问题是:您需要哪种技术让用户获取此文件,而与生成文件需要多长时间以及他们的 Internet 连接有多差无关?

    有许多可能的方法,它们都有自己的缺点。根据您要支持的浏览器,有几个选项。所有这些都需要使用客户端 JavaScript。

    您可能想要使用现代的Server-Sent events,它允许服务器主动触发浏览器中的事件,浏览器可以根据需要响应该事件。

    更经典的方法是通过 HTTPS 进行(长时间)轮询,您可以像以前一样执行此操作,但将客户端和服务器中的超时时间配置为相当大。此外,您需要使用 JavaScript 来重复请求,以防它超时。此外,还建立了一些肮脏的技术来防止超时。

    您可能需要进行一些研究,使用“服务器推送”、“彗星”、“长轮询”等术语。这样做,您可能会阅读有关 WebSockets 的信息(我认为您并不直接需要它)。

    我想如果我是你,我现在会选择使用服务器发送的事件。但您必须自己弄清楚,具体取决于您的具体要求。

    快速浏览一下,这篇文章的介绍可能是一个很好的阅读:https://jersey.java.net/documentation/latest/sse.html

    另外,W3C Server-Sent Events specification 的介绍也不错。引用:

    可以使用 HTTP 301 和 307 重定向事件流请求 与普通 HTTP 请求一样重定向。 客户端将重新连接,如果 连接已关闭;可以告诉客户端停止重新连接使用 HTTP 204 无内容响应代码。

    使用此 API 而不是使用 XMLHttpRequest 或 iframe 允许用户代理更好地利用网络资源 如果用户代理实现者和网络运营商是 能够提前协调。除了其他好处外,这可能会导致 显着节省便携式设备的电池寿命。这是 在下面关于无连接推送的部分中进一步讨论。

    【讨论】:

    • 感谢您的解释!虽然我们最终放弃了导出为 .xls 文件,但您的回答帮助我学到了很多东西。真的很感激。
    【解决方案2】:

    我同意@Jan,服务器发送事件 (SSE) 可能是要走的路。如果你想更花哨,你可以设置一个 celery 任务队列并监听 task_complete 信号,然后通过 SSE 通知用户下载已准备好。这是using SSE in Flask 的示例。这是celery and signaling的链接

    另一种方法是在初始请求中启动异步 Celery 任务,然后继续检查该任务是否通过 setInterval() 客户端中的 ajax 请求完成。该路线只会检查 MyTask.AsyncResult(task_id).state

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-13
      • 2019-11-16
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      相关资源
      最近更新 更多