标签:server-sent-events python ajax pyramid
我正在尝试从我的金字塔应用程序中流式传输服务器发送事件,但我无法弄清楚如何从我的视图中流式传输响应体.这是我正在使用的测试视图(它完全没有实现SSE,只是为了计算流部分):
@view_config(route_name='iter_test')
def iter_test(request):
import time
def test_iter():
i = 0
while True:
i += 1
if i == 5:
raise StopIteration
yield str(time.time())
print time.time()
time.sleep(1)
return test_iter()
这会产生ValueError:无法将视图可调用函数pdiff.views.iter_test的返回值转换为响应对象.返回的值是< generator object test_iter at 0x3dc19b0>.
我已经尝试了返回Response(app_iter = test_iter()),它至少没有错误输出,但它不会响应流 – 它会等到生成器完成后再将响应返回给我的浏览器.
我认识到,每个请求可以简单地返回一个事件并允许客户端在每个事件之后重新连接,但我更喜欢通过从单个请求流式传输多个事件来保留Server-Sent Events的实时性,而不需要重新连接延迟.我怎么能用金字塔做到这一点?
解决方法:
我发现了这个问题.原来我的应用程序代码很好,问题在于Waitress和nginx:
> Waitress,Pyramid使用的默认Web服务器,以18000字节的块缓冲所有输出(有关详细信息,请参阅this issue).
>问题的来源是由我放在我的Pyramid应用程序前面的Web服务器nginx隐藏的,它也缓冲了响应.
(1)可以通过以下任一方式解决:
>在.ini文件中配置send_bytes = 1的女服务员.这可以解决流式传输问题,但会让整个应用程序变得非常慢.正如@Zitrax所提到的,您可以使用更高的值恢复某些速度,但任何高于1的值都会使消息卡在缓冲区中.
>切换到gunicorn.我不知道gunicorn是否只使用较小的缓冲区,或者它是否与app_iter表现得更好,但它有效,并保持我的应用程序快速.
(2)可以通过配置nginx来禁用流路由的缓冲来解决.
你需要在你的nginx conf中设置proxy_buffering.此设置适用于通过proxy_pass托管的网站.如果您没有使用proxy_pass,则可能需要不同的设置.
>您可以根据请求标头配置nginx为每个响应动态启用/禁用缓冲,如this question on the topic所示(EventSource / Server-Sent Events的一个很好的解决方案)
>您也可以在nginx conf中的位置块中配置它.如果您使用EventSource以外的其他内容并且您不希望收到特定标头,或者您正在使用EventSource,但是想要从普通浏览器选项卡调试响应,那么这是很好的,您无法发送接受您的请求中的标头.
标签:server-sent-events,python,ajax,pyramid 来源: https://codeday.me/bug/20191004/1854226.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。