编程语言
首页 > 编程语言> > python – 金字塔流响应体

python – 金字塔流响应体

作者:互联网

我正在尝试从我的金字塔应用程序中流式传输服务器发送事件,但我无法弄清楚如何从我的视图中流式传输响应体.这是我正在使用的测试视图(它完全没有实现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