Как исправить остановку потребителей каналов django для обработки сообщений, отправляемых в группы
Отправка сообщений в группы с помощью group_send()
вдруг перестает работать через некоторое время. Метод обработчика потребителя больше не вызывается.
Перезапуск daphne
исправляет проблему в течение некоторого времени.
подробности
В журналах не отображается никаких ошибок, просто сообщения больше не обрабатываются потребителями.
Я использую следующие библиотеки:
- aioredis == 1.2.0
- asgiref == 2.3.2
- Каналы-Redis == 2.3.2
- Каналы == 2.1.6
- Дафна == 2.2.4
- Джанго == 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()
для потребителей не работает.
1 ответ
Существует известная ошибка, приводящая к разрыву соединений через некоторое время для приложений Channels, работающих в Python 3.5. Обновление до Python 3.6 для возможного исправления
Я столкнулся с этой проблемой с Python3.8. Поэтому я исправил это, переключившись на Python3.6
Каналы Django - Клиент иногда получает сообщение, а не в другой раз, пока не получит его вообще