用例-一些用户数据正在后端(烧瓶)中加载,并且进度通过加载栏显示在前端。后端有一个生成器,该生成器加载数据并保持 yielding 进度(此生成器使用stream_with_context作为响应返回)。前端使用javascript EventSource 对象查询烧瓶视图。
代码:
@app.route("/progress", methods=['GET'])
def progress():
gen = get_user_data()
return Response(stream_with_context(gen), mimetype= 'text/event-stream')
def get_user_data():
n = 100 (number of data points to be loaded)
for i in range(1,n+1):
#load data
yield "data:" + str((float(i)/(n))*100) + "\n\n"
yield "data:" + "close" + "\n\n"
这在我的本地环境下工作正常。但是,当我将其部署在 google app引擎灵活环境上时,加载栏直接从0变为100。也就是说,不是每次生成器产生收益时前端都获得更新,一次(生成器完成执行后)所有EventSource消息。
我的app.yaml:
runtime: python
env: flex
entrypoint: gunicorn --timeout 240 -b :$PORT app:app
runtime_config:
python_version: 2
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
关于如何在Google App Engine上运行它的任何想法吗?
答案 0 :(得分:1)
根据this documentation,“ EventSource实例打开了与HTTP服务器的持久连接”。根据{{3}}提供的说明,该解决方案无法在App Engine中工作:
您可以尝试在自己的计算机上声明“ Content-Type:文本/事件流” 自己的原始App Engine处理程序,并使用EventSource
浏览器中的对象可启动保持活动连接。问题 是,App Engine等待您的应用上的处理程序进入
return fully before flushing the buffer and sending the response data
。你可以找到 记录在这里:https://developer.mozilla.org/en-US/docs/Web/API/EventSource 对于java https://cloud.google.com/appengine/docs/java/requests#Java_Responses 对于python https://cloud.google.com/appengine/docs/python/requests#Python_Responses 对于PHP https://cloud.google.com/appengine/docs/php/requests#PHP_Responses 去。
这实际上意味着您的信息流将不会 “保持活动状态”,并且每次发送一个响应时都会关闭。或者,如果你 像大多数人一样,在服务器端实施服务器发送的事件代码, 它将缓冲所有响应,最后只发送所有响应 当它终止时。
当前有几种复杂的解决方法:
根据Firebase中的消息#231,将很快提供一种更简单的方法。 Flex WebSockets Beta的发布即将推出,但对于标准环境,它距离“至少一年”。如果您想获得有关评论和更新的自动通知,请为issuetracker帖子加注星标。