服务器发送的带有金字塔的事件-如何检测到客户端的连接是否丢失

时间:2019-03-17 16:49:03

标签: pyramid server-sent-events

我有一个发送SSE消息的金字塔应用程序。它的基本工作原理如下:

def message_generator():
    for i in range(100):
        print("Sending message:" + str(i))
        yield "data: %s\n\n" % json.dumps({'message': str(i)})
        time.sleep(random.randint(1, 10))

@view_config(route_name='events')
def events(request):
    headers = [('Content-Type', 'text/event-stream'),
               ('Cache-Control', 'no-cache')]
    response = Response(headerlist=headers)
    response.app_iter = message_generator()
    return response

当我浏览到/ events时,我得到了事件。当我移到另一个页面时,事件停止,当我关闭浏览器时,事件停止。

例如,如果我在/ events中并且关闭了计算机,就会发生问题。服务器不知道客户端丢失了消息,而message_generator继续向无效对象发送消息。

在此页面中:A Look at Server-Sent Events提及:

  

...服务器应检测到此情况(客户端停止时)并停止   发送更多事件,因为客户端不再监听它们。   如果服务器不执行此操作,则它实际上将在发送   事件变成虚无。

有没有办法用金字塔检测到这一点?我尝试过

request.add_finished_callback()

但是此回调似乎是用

调用的
return response

我将Gunicorn和gevent一起使用来启动服务器。

任何想法都受到赞赏

1 个答案:

答案 0 :(得分:0)

从PEP 3333:

  

返回生成器或其他自定义迭代器的应用程序不应假定整个迭代器都将被消耗,因为服务器可能会提前关闭它。

基本上,当客户端断开连接时,WSGI服务器“应该”在close()上调用app_iter方法(所有生成器(例如您的示例中的生成器都自动支持))。但是,并不需要服务器来执行此操作,而且似乎许多WSGI服务器都不需要。例如,您提到了gunicorn(我尚未独立验证),但我确实确认女服务员也没有。结果,我在女服务员上打开了[1],并且一直在进行修复。 WSGI环境中的流响应充其量是不稳定的,通常取决于服务器。例如,在女服务员上,您需要设置send_bytes=0以避免它缓冲响应数据。

[1] https://github.com/Pylons/waitress/issues/236