我有一个发送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不断向void发送消息。
在这个页面中:A Look at Server-Sent Events提到这个:
...服务器应该检测到这一点(当客户端停止时)并停止发送更多事件,因为客户端不再监听它们。如果服务器没有这样做,那么它基本上将事件发送到void。
有没有办法用金字塔来检测这个?我试过了
request.add_finished_callback()
但这个回调似乎被调用了
return response
我使用Gunicorn和gevent来启动服务器。
任何想法都非常感谢
从PEP 3333:
返回生成器或其他自定义迭代器的应用程序不应假设将使用整个迭代器,因为服务器可能会提前关闭它。
基本上,当客户端断开连接时,WSGI服务器“应该”在close()
上调用app_iter
方法(所有生成器,例如在您的示例中,自动支持)。但是,服务器不需要这样做,并且似乎许多WSGI服务器不这样做。例如,你提到gunicorn(我没有独立验证),但我确实证实女服务员也没有。因此,我在服务员上打开了[1],并且一直在努力修复。 WSGI环境中的流式响应最多是不稳定的,通常取决于服务器。例如,在女服务员上,您需要设置send_bytes=0
以避免缓冲响应数据。