spi*_*ech 10 python ajax pyramid server-sent-events
我正在尝试从我的金字塔应用程序中流式传输服务器发送事件,但我无法弄清楚如何从我的视图中流式传输响应体.这是我正在使用的测试视图(它完全没有实现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()
Run Code Online (Sandbox Code Playgroud)
这产生了 ValueError: Could not convert return value of the view callable function pdiff.views.iter_test into a response object. The value returned was <generator object test_iter at 0x3dc19b0>.
我尝试过return Response(app_iter=test_iter()),至少没有错误,但它没有流响应 - 它等到生成器完成后才将响应返回给我的浏览器.
我认识到,每个请求只能返回一个事件,并允许客户端在每个事件后重新连接,但我更喜欢通过从单个请求流式传输多个事件来保留Server-Sent Events的实时性,而不需要重新连接延迟.我怎么能用金字塔做到这一点?
我发现了这个问题.原来我的应用程序代码很好,问题在于Waitress和nginx:
女服务器Pyramid使用的默认Web服务器以18000字节的块缓冲所有输出(有关详细信息,请参阅此问题).
问题的根源是nginx,我放在Pyramid应用程序前面的Web服务器,这也缓冲了响应.
(1)可以通过以下任一方式解决:
send_bytes = 1在.ini文件中配置女服务员.这可以解决流式传输问题,但会让整个应用程序变得非常慢.正如@Zitrax所提到的,您可以使用更高的值恢复某些速度,但任何高于1的值都会使消息卡在缓冲区中.
切换到gunicorn.我不知道gunicorn是否只使用较小的缓冲区,或者它是否表现得更好app_iter,但它有效,并保持我的应用程序快速.
(2)可以通过配置nginx来禁用流路由的缓冲来解决.
你需要设置proxy_buffering off你的nginx conf.此设置适用于通过托管的网站proxy_pass.如果您不使用proxy_pass,则可能需要不同的设置.
您可以配置nginx以根据请求标头为每个响应动态启用/禁用缓冲,如关于主题的此问题所示(EventSource/Server-Sent Events的良好解决方案)
您也可以location在nginx conf 中的块中进行配置.如果您使用EventSource以外的其他内容并且您不希望收到特定标头,或者您正在使用EventSource,但是想要从普通浏览器选项卡调试响应,那么这是很好的,您无法在其中发送Accept标头在你的请求中.
| 归档时间: |
|
| 查看次数: |
3505 次 |
| 最近记录: |