如何修复 Django 频道消费者停止处理发送给群组的消息
How to fix django channels consumers stopping to handle messages send to groups
使用 group_send()
向群组发送消息一段时间后突然停止工作。不再调用消费者的处理程序方法。
重新启动 daphne
可以解决问题一段时间。
详情
日志中没有任何错误出现,只是消费者不再处理消息。
我正在使用以下库:
- aioredis==1.2.0
- asgiref==2.3.2
- channels-redis==2.3.2
- 频道==2.1.6
- 达芙妮==2.2.4
- django==2.1.5
- redis==3.0.1
代码
# settings.py
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {"hosts": [("localhost", "6379")]},
}
}
# views.py
class ReceiveEventView(APIView):
def post(self, request, *args, **kwargs):
# payload: {"type": "event_triggered", "group": "warning", "message": "Button pressed"}
# or
# payload: {"type": "event_triggered", "group": "danger", "message": "Red Button pressed"}
payload = json.loads(request.POST.get("payload", "{}"))
if (payload.get("type") == "event_triggered"):
async_to_sync(channel_layer.group_send)(payload.get("group"), payload)
return HttpResponse(status=204)
# consumers.py
class EventConsumer(WebsocketConsumer):
def connect(self):
if not self.scope["user"].is_authenticated:
return
self.accept()
for group in get_subscriptions(self.scope["user"]):
async_to_sync(self.channel_layer.group_add)(group, self.channel_name)
def disconnect(self, close_code):
if not self.scope["user"].is_authenticated:
return
for group in get_subscriptions(self.scope["user"]):
async_to_sync(self.channel_layer.group_discard)(group, self.channel_name)
def event_triggered(self, event):
logger.debug("Consumer::event_triggered()")
self.send(text_data=json.dumps(event))
预期和实际结果
有一段时间 Consumer::event_triggered()
出现在日志记录中,但突然停止。通过 WebSocket 从浏览器接收消息仍然有效。只是从 group_send()
到消费者的传输中断了。
对于 Python 3.5 中的频道应用程序 运行,存在 known bug 导致连接中断的问题。更新到 Python 3.6 以获得可能的修复
我在 Python3.8 遇到过这个问题。所以我通过切换到 Python3.6
来修复它
使用 group_send()
向群组发送消息一段时间后突然停止工作。不再调用消费者的处理程序方法。
重新启动 daphne
可以解决问题一段时间。
详情
日志中没有任何错误出现,只是消费者不再处理消息。
我正在使用以下库:
- aioredis==1.2.0
- asgiref==2.3.2
- channels-redis==2.3.2
- 频道==2.1.6
- 达芙妮==2.2.4
- django==2.1.5
- redis==3.0.1
代码
# settings.py
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {"hosts": [("localhost", "6379")]},
}
}
# views.py
class ReceiveEventView(APIView):
def post(self, request, *args, **kwargs):
# payload: {"type": "event_triggered", "group": "warning", "message": "Button pressed"}
# or
# payload: {"type": "event_triggered", "group": "danger", "message": "Red Button pressed"}
payload = json.loads(request.POST.get("payload", "{}"))
if (payload.get("type") == "event_triggered"):
async_to_sync(channel_layer.group_send)(payload.get("group"), payload)
return HttpResponse(status=204)
# consumers.py
class EventConsumer(WebsocketConsumer):
def connect(self):
if not self.scope["user"].is_authenticated:
return
self.accept()
for group in get_subscriptions(self.scope["user"]):
async_to_sync(self.channel_layer.group_add)(group, self.channel_name)
def disconnect(self, close_code):
if not self.scope["user"].is_authenticated:
return
for group in get_subscriptions(self.scope["user"]):
async_to_sync(self.channel_layer.group_discard)(group, self.channel_name)
def event_triggered(self, event):
logger.debug("Consumer::event_triggered()")
self.send(text_data=json.dumps(event))
预期和实际结果
有一段时间 Consumer::event_triggered()
出现在日志记录中,但突然停止。通过 WebSocket 从浏览器接收消息仍然有效。只是从 group_send()
到消费者的传输中断了。
对于 Python 3.5 中的频道应用程序 运行,存在 known bug 导致连接中断的问题。更新到 Python 3.6 以获得可能的修复
我在 Python3.8 遇到过这个问题。所以我通过切换到 Python3.6
来修复它