Я развертываю проект Django в облаке Openshift. В этом проекте используются каналы и веб-узлы, чтобы он работал асинхронно. Проблема в том, что я не могу успешно подключить веб-сокеты из браузера к серверу Daphne, который я запустил на стороне сервера.
Я использую картриджи django (python2.7) и redis, чтобы он работал .
Скрипт post_deploy, который я использую, выглядит так:
...
python manage.py runworker -v2 && daphne myapp.asgi:channel_layer -p 8443 -b $OPENSHIFT_REDIS_HOST -v2
...
Вот моя конфигурация Django. В settings.py:
...
ALLOWED_HOSTS = [
socket.gethostname(),
os.environ.get('OPENSHIFT_APP_DNS'),
]
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"CONFIG": {
"hosts": [("redis://:{}@{}:{}/0").format(
OPENSHIFT_REDIS_PASSWORD,
OPENSHIFT_REDIS_HOST,
OPENSHIFT_REDIS_PORT
)],
},
"ROUTING": "myapp.routing.channel_routing",
},
}
...
В routing.py:
...
ws_routing = [
routing.route("websocket.connect", ws_connect),
routing.route("websocket.receive", ws_receive),
routing.route("websocket.disconnect", ws_disconnect),
]
channel_routing = [
include(ws_routing, path=r"^/sync"),
]
...
В consumer.py;
def ws_connect(message):
Group("notifications").add(message.reply_channel)
def ws_disconnect(message):
Group("notifications").discard(message.reply_channel)
def ws_receive(message):
print "Receiving: '%s' from %s" % (message.content['text'], message.content['reply_channel'])
На стороне клиента я запускаю этот код:
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
var path = ws_scheme+'://'+window.location.host + ':8443/sync';
var ws = new WebSocket(path);
ws.onmessage = function(message) {
console.log(message.data);
}
ws.onopen = function() {
this.send('WS Connecting to receive updates!');
}
Обратите внимание, что я использую порт 8443 в настройках Daphne и WebSockets из-за эту документацию. Кроме того, Дафна привязана к адресу OPENSHIFT_HOST, потому что невозможно привязать его к 0.0.0.0 в Openshift (проблема с разрешением)
Результат выглядит так:
На стороне клиента все выглядит нормально, но если вы помните, в consumer.py у меня было следующее:
def ws_receive(message):
print "Receiving: '%s' from %s" % (message.content['text'], message.content['reply_channel'])
Итак, в моем терминале сервер должен печатать что-то вроде: «Receiving: from», но это не так. Что мне здесь не хватает?
tl; dr: клиентский веб-сокет выглядит так, как будто он подключен правильно, но сервер не распечатывает сообщение для подтверждения.