Сервер Daphne не может подключиться к веб-узлам по HTTPS

Я развертываю проект 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 (проблема с разрешением)

Результат выглядит так:

первый

second

третий

На стороне клиента все выглядит нормально, но если вы помните, в consumer.py у меня было следующее:

def ws_receive(message):
    print "Receiving: '%s' from %s" % (message.content['text'], message.content['reply_channel'])

Итак, в моем терминале сервер должен печатать что-то вроде: «Receiving: from», но это не так. Что мне здесь не хватает?

tl; dr: клиентский веб-сокет выглядит так, как будто он подключен правильно, но сервер не распечатывает сообщение для подтверждения.


person pazitos10    schedule 16.07.2016    source источник


Ответы (1)


Мне удалось заставить это работать. Проблема, похоже, связана с переадресацией портов, из-за которой я не мог подключать веб-сокеты через сервер apache в облаке openshift к моему серверу daphne.

Для решения этой проблемы:

1) С картриджем по умолчанию для проектов django мне не удалось изменить файл apache conf и даже обновить apache, чтобы установить mod_proxy_wstunnel для поддержки веб-сокетов, поэтому я решил изменить его. Кроме того, mod_proxy_wstunnel работает с apache 2.4, но картридж по умолчанию использует 2.2.

Каналы docs, рекомендуют использовать nginx. Итак, я нашел картридж, который позволяет мне использовать его вместе с uwsgi. и джанго.

Я выполнил инструкции в этом репозитории, но перед тем, как запустить свой код, я немного подправил хуки действий, чтобы получить самые последние версии этих пакетов, и заменил образец проекта django своим. То же самое проделал и с файлом requirements.txt.

2) После нажатия я добавил картридж redis.

3) Затем я приступил к настройке uwsgi.yaml и nginx.conf, которые картридж предоставляет в качестве шаблонов, чтобы установить правильные значения:

uwsgi.yaml

uwsgi:
    socket: $OPENSHIFT_DIY_IP:15005
    pidfile: $OPENSHIFT_TMP_DIR/uwsgi.pid
    pythonpath: $OPENSHIFT_REPO_DIR/$APP_DIR
    module: $APP_NAME.wsgi:application
    virtualenv: $OPENSHIFT_DATA_DIR/virtualenv

nginx.conf

...
http {
   ...
   server {
       listen      $OPENSHIFT_DIY_IP:$OPENSHIFT_DIY_PORT;
       server_name localhost;

       set_real_ip_from    $OPENSHIFT_DIY_IP;
       real_ip_header      X-Forwarded-For;

       location / {
           uwsgi_pass  $OPENSHIFT_DIY_IP:15005;
           include     uwsgi_params;
       }

       location /sync {
           proxy_pass http://$OPENSHIFT_DIY_IP:8443;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
       }
       ...
  }
}

В моем сценарии post_deploy у меня есть следующее:

...
python manage.py runworker -v2 &
daphne myapp.asgi:channel_layer -p 8443 -b $OPENSHIFT_DIY_IP -v2 &
...

Итак, Дафна слушает $ OPENSHIFT_DIY_IP: 8443, и когда nginx получает запрос от веб-сокетов, подобный этому:

 var path = 'wss://'+window.location.host + ':8443/sync';
 var ws = new WebSocket(path);
 ws.onmessage = function(message) {
     alert(message.data);
 }
 ws.onopen = function() {
     this.send('WS Connecting to receive updates!');
 }

Теперь я вижу:

терминал

И в браузере:

alert

Так что я знаю, что это работает. Надеюсь, это может помочь кому-то другому, кроме меня.

person pazitos10    schedule 22.07.2016