Django 频道 - websocket_disconnect 在循环中被调用

Posted

技术标签:

【中文标题】Django 频道 - websocket_disconnect 在循环中被调用【英文标题】:Django channels - websocket_disconnect being called in loop 【发布时间】:2019-03-28 16:28:48 【问题描述】:

我正在使用 Django-channels 以便在创建模型的新实例时提供即时通知。

为此,我使用 django-channels 和 SyncConsumer。一切正常,除了 websocket_disconnect 被循环调用 n 次。

这是我的消费者代码:

class BaseConsumer(SyncConsumer):

    def websocket_connect(self, event):
        self.send("type": "websocket.accept")

    def websocket_receive(self, event):
        # do some stuff here

    def websocket_disconnect(self, event):
        print("websocket_disconnect")

这是来自我的网络服务器的日志:

api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect
api_1    | websocket_disconnect

这种情况一直持续下去,直到我停止 Web 服务器。

当我手动关闭前端的连接(我使用的是 javascript,所以我调用 ws.close())和关闭浏览器选项卡/客户端时,都会发生这种行为。

在我看来,这不符合正确的行为,因为我可以听到我的电脑迷们在疯狂地工作。连接关闭后如何阻止此方法被触发?因为连接本身会正确关闭,我可以在 javascript onclose 方法中进行验证,该方法仅在前端触发一次。

有没有其他人经历过这样的事情?

谢谢!

【问题讨论】:

【参考方案1】:

我有这个问题好几天了,在 *** 上发布我的问题几分钟后,我就找到了解决问题的方法。

深入阅读文档,我发现了以下内容:

当连接到消费者的套接字或连接关闭时 - 由您或客户 - 您可能会收到发送给您的事件 (例如,http.disconnect 或 websocket.disconnect),以及您的 应用程序实例将有很短的时间进行操作 它。

完成断开后清理后,您需要 引发 channels.exceptions.StopConsumer 以停止 ASGI 应用程序 干净地让服务器清理它。如果你让它运行 - 通过 不引发此异常 - 服务器将访问其应用程序 关闭超时(在 Daphne 中默认为 10 秒)然后杀死 您的应用程序并发出警告。

下面的通用消费者会为您执行此操作,因此仅在以下情况下才需要 您正在编写自己的基于 AsyncConsumer 的消费者类或 同步消费者。

(https://channels.readthedocs.io/en/latest/topics/consumers.html?highlight=websocket.disconnect#closing-consumers)

总而言之,为了正确关闭连接,需要提高StopConsumer

希望这个答案能解决其他人的一些头痛问题!

【讨论】:

以上是关于Django 频道 - websocket_disconnect 在循环中被调用的主要内容,如果未能解决你的问题,请参考以下文章

使用 django 频道时如何使用频道而不是组?

Django 频道“组订阅中 N 个频道中的 ERROR Y 超出容量”

使用 django 频道的 heroku 的正确 procfile / 要求是啥?

django 频道集成问题,websocket.receive 不听

未处理 Django 频道 websocket.receive

在 nginx 上部署 django 频道