Django频道-在循环中调用websocket_disconnect

时间:2019-03-28 16:28:48

标签: django websocket django-channels

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

为此,我正在使用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 个答案:

答案 0 :(得分:0)

我在StackOverFlow上发布问题几天后才有这个问题,我能够找到解决问题的方法。

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

  

关闭与消费者连接的插座或连接时-   由您或客户-您很可能会收到一个发送给您的事件   (例如,http.disconnect或websocket.disconnect),并且您的   应用程序实例将在短时间内采取行动   它。

     

完成断开后的清理后,您需要   引发channels.exceptions.StopConsumer以停止ASGI应用程序   干净地让服务器清理它。如果让它继续运行-   没有引发此异常-服务器将到达其应用程序   关闭超时(达芙妮默认为10秒),然后终止   您的应用程序并发出警告。

     

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

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

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

希望这个答案将来可以解决其他人的头痛!