云跑真的可以串流吗?它在抱怨内容长度

问题描述 投票:0回答:1

我在 Cloud Run 上运行,并设置了从 Flask 到浏览器的流式传输。它似乎可以很好地传输二进制数据(在本例中它已被腌制和压缩)。

def transmit_binary_data(N):                   # Yield compressed data in chunks 
   chunk_size = 16384                          # Maybe too small?
   print("Start transmitting compressed:", N, "chunk size:", chunk_size)
   for i in range(0, N, chunk_size): 
      yield e[i:i+chunk_size]

with app.app_context():
   response = make_response(Response(transmit_binary_data(content_length), 
                             mimetype="application/octet-stream"))
   response.headers['Content-Length'] = content_length
   return response

在 javascript 方面,我在块进来时累积它们,然后解压缩和解泡。完美。

但它不适用于非常大(GB)的数据集。我收到日志错误:

textPayload: "Response size was too large. Please consider reducing response size."

我认为可能发生的情况是 Cloud Run 在服务器和客户端之间创建了一个中间缓冲区,而该缓冲区太大了。

或者也许错误在于我天真地告诉 Cloud Run 最终将发送多少数据:::

response.headers['Content-Length'] = content_length
?

感谢建议。

flask streaming google-cloud-run
1个回答
0
投票

好吧,是的,我搞砸了:如果您将

['Content-Length']
设置为标头,那么 Cloud Run 实际上会假设您不想流式传输数据,即使 mime 类型设置为流式传输也是如此。哎呀。

但是我想要一个下载进度条,这意味着浏览器需要在开始下载之前知道长度。我创建了一个新的标头变量

[x-total-length]
并将其设置为字节总数。

response = make_response(Response(transmit_binary_data(content_length), mimetype="application/octet-stream"))
response.headers['x-total-length'] = content_length

# DONT DO THIS:: response.headers['Content-Length'] = content_length

流媒体开始完美运行。除了进度条不起作用。结果是为了使

[x-total-length]
对浏览器可见,我必须编辑 Flask 的
_init_.py
使其成为有效条目:

    @app.after_request
    def after_request(response):
#        Access-Control-Allow-Origin Stuff...:

        response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
        response.headers.add('Access-Control-Expose-Headers', 'x-total-length') #for streaming data

现在一切正常了。

© www.soinside.com 2019 - 2024. All rights reserved.