使用Django和Heroku上的服务器推送事件,如何检测客户端断开连接?

4
Heroku关于发送流式响应的文档中提到:(传送门):“如果要发送流式响应,例如使用服务器推送事件(server-sent events),必须检测客户端何时挂起,并确保您的应用服务器立即关闭连接。”
我一直在Heroku上使用Django中的服务器推送事件(SSE),并使用django-sse。它使用一个迭代器无限循环地从Redis发布/订阅频道读取消息并将其发送到客户端。
def iterator(self):
    connection = _connect()
    pubsub = connection.pubsub()
    pubsub.subscribe(self.get_redis_channel())

    for message in pubsub.listen():
        if message['type'] == 'message':
            event, data = json.loads(message['data'])
            self.sse.add_message(event, data)
            yield

问题在于,如果客户端断开连接,我希望能够跳出循环,这样我就可以关闭与Redis的连接。如何检测客户端何时断开连接?


你确定连接不会自动关闭吗?你可以使用redis-cli中的CLIENT LIST命令来检查Django Redis客户端是否仍然连接。 - igorw
它在Heroku上无法运行(尽管在本地运行时可以)。我第一次注意到问题是当我使用我的测试网站时,即使我是唯一的用户,也会耗尽Redis连接(免费的RedisToGo计划最多有10个连接)。后来我通过redis-cliCLIENT LIST确认了连接确实没有自动关闭。 - Tom Offermann
1个回答

2
我在Heroku上使用Scala Play2应用程序时遇到了类似的问题,无法检测客户端通过close()、refresh或关闭窗口关闭SSE连接。启用新的Heroku Labs websockets feature功能解决了我的问题。
更新:
我向Heroku支持团队提出了问题并告诉他们我的经历。这是他们的回复。
引用: “Lloyd,你好, 这是一个已知的问题,你的结论是正确的,新的WebSocket端点可以解决这个问题。我们不打算解决现有端点的问题,但最终会将WebSocket端点推广到更广泛的受众中。 最好, Jake”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接