Django Channels Worker не отвечает на websocket.connect
У меня проблема с каналами Django. Дафна принимает запросы WebSocket CONNECT правильно, но затем рабочие не отвечают на запрос с помощью предоставленного метода в consumer.py. Дело в том, что это происходит только большую часть времени. Иногда он отвечает с помощью метода в consumer.py, но большую часть времени работник не отвечает вообще. У меня есть дублированный код, работающий нормально в среде vagrant (trusty64), но код ведет себя так же, как на реальной машине trusty64. Следует отметить, что на машине trusty64, на которой размещено приложение, также запущено другое приложение (одновременно работает около 4 приложений).
У меня есть Rouing.py настроен так
from channels import route
from app.consumers import connect_tracking, disconnect_tracking
channel_routing = [
route("websocket.connect", connect_tracking, path=r'^/websocket/tms/tracking/stream/$'),
route("websocket.disconnect", disconnect_tracking, path=r'^/websocket/tms/tracking/stream/$'),
]
с соответствующим consumer.py, который выглядит следующим образом
import json
from channels import Group
from channels.sessions import channel_session
from channels.auth import http_session_user, channel_session_user, channel_session_user_from_http
from django.conf import settings
@channel_session_user_from_http
def connect_tracking(message):
group_name = settings.TRACKING_GROUP_NAME
print "%s is joining %s" % (message.user, group_name)
Group(group_name).add(message.reply_channel)
@channel_session_user
def disconnect_tracking(message):
group_name = settings.TRACKING_GROUP_NAME
print "%s is joining %s" % (message.user, group_name)
Group(group_name).discard(message.reply_channel)
и некоторые каналы, связанные строки в settings.py, как это
redis_host = os.environ.get('REDIS_HOST', 'localhost')
CHANNEL_LAYERS = {
"default": {
# This example app uses the Redis channel layer implementation asgi_redis
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [(redis_host, 6379)],
},
"ROUTING": "tms_app.routing.channel_routing",
},
}
ссылаясь на другой вопрос, я попытался запустить Дафни и работник, как это
daphne tms_app.asgi:channel_layer --port 9015 --bind 0.0.0.0 -v2
python manage.py runworker -v3
Я записал Дафни и журнал работника, это выглядит так
Дафна журнал:
2016-12-30 17:00:18,870 INFO Starting server at 0.0.0.0:9015, channel layer tms_app.asgi:channel_layer
2016-12-30 17:00:26,788 DEBUG WebSocket open for websocket.send!APpWONQKKDXR
192.168.31.197:48933 - - [30/Dec/2016:17:00:26] "WSCONNECT /websocket/tms/tracking/stream/" - -
2016-12-30 17:00:26,790 DEBUG Upgraded connection http.response!sqlMPEEtolDP to WebSocket websocket.send!APpWONQKKDXR
соответствующий рабочий журнал:
2016-12-30 17:00:22,265 - INFO - runworker - Running worker against channel layer default (asgi_redis.core.RedisChannelLayer)
2016-12-30 17:00:22,265 - INFO - worker - Listening on channels http.request, websocket.connect, websocket.disconnect, websocket.receive
Как вы можете видеть, когда есть событие WSCONNECT, работник не отвечает на него.
Есть еще один вопрос, близкий к этой проблеме, который был решен путем понижения Twisted до 16.2, но он не работает для меня.
ОБНОВЛЕНИЕ 3 января 2017
Я не могу воспроизвести проблему на локальном бродячем компьютере, несмотря на использование того же кода и одинаковых настроек для nginx, supervisor, gunicorn и daphne. Я попытался изменить настройки слоев канала, чтобы он использовал IPC вместо redis, и он работает. Вот настройки:
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_ipc.IPCChannelLayer",
"ROUTING": "tms_app.routing.channel_routing",
"CONFIG": {
"prefix": "tms",
},
},
}
Однако это не решает текущую проблему, так как я собираюсь использовать канальные уровни Redis, потому что их легче масштабировать по сравнению с IPC. Значит ли это что-то не так с моим сервером Redis?
1 ответ
Я думаю, что причина, по которой ваше Соединение не завершается, в том, что вы не отправляете сообщение о принятии, например так:message.reply_channel.send({'accept': True})
Это то, что работает для моей версии каналов, но вы должны проверить документы для вашей версии, чтобы убедиться, что работает для вас