Django 频道错误“关闭时间太长并被杀死”。

Posted

技术标签:

【中文标题】Django 频道错误“关闭时间太长并被杀死”。【英文标题】:Django channel Error "took too long to shut down and was killed." 【发布时间】: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"
    )

如何解决这个问题?

【问题讨论】:

【参考方案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。当心!

【讨论】:

以上是关于Django 频道错误“关闭时间太长并被杀死”。的主要内容,如果未能解决你的问题,请参考以下文章

Windows错误10061 - Django频道

Django 频道中的消费者

在 Django 频道上找不到路径

Django 频道 + Elastic Beanstalk

Django 频道 + 在发布请求后发送 websocket 消息

开始使用 Django 频道时遇到问题