【问题标题】:Django channel Error "took too long to shut down and was killed."Django 频道错误“关闭时间太长并被杀死”。
【发布时间】:2020-11-01 10:10:38
【问题描述】:

我在控制台日志中收到此错误,并且在提交表单时它一直在加载,但不会将数据发布到服务器。

/home/Python/Working/Benutzerverwaltung/env/lib/python3.6/site-packages/channels/sessions.py:183>
wait_for=<Future pending cb=[<TaskWakeupMethWrapper object at
0x7fab9fe51408>()]>> for connection <WebSocketProtocol
client=['127.0.0.1', 59462] path=b'/ws/stream/Sales'> took too long to
shut down and was killed.

这是我关闭频道的代码。

async def disconnect(self, code):
    async_to_sync(self.channel_layer.group_discard)(
        self.room_group_name,
        self.channel
    )
    await self.close()

async def websocket_disconnect(self, event):
    print("Disconnect", event)
    await self.send({
        "type": "websocket.close"
    })

如何解决这个问题?

【问题讨论】:

    标签: python-3.x django websocket django-channels django-redis


    【解决方案1】:

    这个错误主要是因为协程挂起的时间比它应该的要长。

    这个具体案例

    在这种情况下,AsyncWebsocketConsumer.websocket_disconnect() 被覆盖但没有调用super(),这意味着StopConsumer() 没有运行(请参阅channels/generic/websocket.py:228)。也许根本不要覆盖websocket_disconnect,因为在这个例子中没有任何东西可以证明它是正确的。

    还要注意async_to_sync 是为同步消费者设计的,但这是一个异步消费者。而是使用:

    await self.channel_layer.group_discard(
        self.room_group_name,
        self.channel
    )
    

    await self.close() 不是必需的,因为已断开连接。删除该行。

    AsyncHttpConsumer

    同样在AsyncHttpConsumer 中,我经常犯的错误是调用await self.send_response(...) 但之后忘记调用return,所以函数会在你没想到的时候继续运行。

    AsyncHttpConsumer 也有一个 open bug report 表示不会在 handle() 中显示异常。目前唯一的选择是添加额外的打印/记录行来确定什么正在/没有运行。

    小心 django-debug-toolbar

    另外值得注意的是,将debug-toolbar 添加到您的INSTALLED_APPS 将使您的异步消费者中的异常静音。见讨论here。当心!

    【讨论】:

      猜你喜欢
      • 2021-05-14
      • 2023-01-25
      • 1970-01-01
      • 2017-08-11
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多