Python Quart/Hypercorn 流式响应导致 net::ERR_HTTP2_PROTOCOL_ERROR 200

Posted

技术标签:

【中文标题】Python Quart/Hypercorn 流式响应导致 net::ERR_HTTP2_PROTOCOL_ERROR 200【英文标题】:Python Quart/Hypercorn streamed response causing net::ERR_HTTP2_PROTOCOL_ERROR 200 【发布时间】:2020-07-02 00:21:23 【问题描述】:

我有一个 Quart 应用程序,我通过它将响应流回客户端。我正在使用 asyncio.sleep 来延迟响应完成,如果我将延迟设置为 59 秒,一切正常。流完成没有任何问题。如果我将时间增加到 120 秒,则响应似乎超时。这是客户端接收到流的第一部分,但大约 60 秒后,浏览器在 Chrome 中抛出错误:net::ERR_HTTP2_PROTOCOL_ERROR 200。Firefox 抛出 TypeError。

我在 nginx 中使用 Hypercorn。

hypercorn config.py 文件内容如下:

Shutdown_timeout = 123.0
ssl_handshake_timeout = 123.0
startup_timeout = 123.0

nginx.conf中的相关设置:

location @proxy_to_app 
proxy_read_timout = 600s

我不知道如何解决这个问题。

我找到了问题的根源。它与 Quart、Hypercorn 或 Nginx 无关。问题在于 Cloudflare 和 http2,它是由 WriteTimeout 引起的。看到这个答案: What's the net::ERR_HTTP2_PROTOCOL_ERROR about?

接下来的问题是,如何在 Cloudlfare 中进行更改。

我没有将 Quart 配置为在 http2 中工作,这有帮助吗?

【问题讨论】:

版本信息:Python 3.7、Quart 0..6.13、Hypercorn 0.5.4、ubuntu 18.04 上的 nginx 1.14.0 我的理解是,这是由于保持连接空闲造成的。那是在服务器执行睡眠时。因此,一种解决方案是将睡眠分成 2 或 3 个部分,并在每个部分之间向客户端发送一个空字符串,以保持连接处于活动状态。 【参考方案1】:

我找到的唯一解决方案是中断睡眠并向客户端发送临时数据以保持连接处于活动状态。

async def async_generator():
      content_arr = [
          json.dumps('first':'some data'),
          json.dumps('alive':''),  #required to http2 connection alive
          json.dumps('final' : 'final data')
      ]
      for i,html in enumerate(content_arr):
          print(i)
          if i > 0:
              await asyncio.sleep(59)  #this delays sending the final data 118 seconds
          yield html.encode()

【讨论】:

以上是关于Python Quart/Hypercorn 流式响应导致 net::ERR_HTTP2_PROTOCOL_ERROR 200的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop pig latin 无法通过 python 脚本流式传输

如何从 Python 中的 Youtube URL 流式传输音频(无需下载)?

在 Python 中流式传输标准输入/标准输出

python 用蟒蛇实现的日志流式分析

Python - Django:使用 HttpResponse 流式传输视频/mp4 文件

使用 Python 和 Flask 流式传输数据