2016-07-16 6 views
2

Я развертываю проект Django в облаке Openshift. Этот проект использует channels и Websockets, чтобы заставить его работать асинхронно. Проблема в том, что я не могу успешно подключить веб-порты из браузера к серверу Daphne, который я запускал на стороне сервера.Сервер Daphne не может соединяться с websockets на HTTPS

Я использую картриджи 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"), 
] 
... 

В consumers.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 в настройках Дафна и WebSockets настройки из-this документации. Кроме того, Дафна обязан OPENSHIFT_HOST адрес, поскольку не представляется возможным связать его с 0.0.0.0 в OpenShift (проблема разрешения)

Результат выглядит следующим образом:

first

second

third

Все выглядит нормально на стороне клиента, но если вы помните, в consumer.py У меня было это:

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

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

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

ответ

4

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

Чтобы решить эту проблему:

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

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

Я следовал инструкциям в этом репо, но перед тем, как нажимать мой код, я немного изменил действия, чтобы получить последние версии этих пакетов, и заменил образец проекта django на мой. Я сделал то же самое с требованиями. 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 получает запрос от WebSockets, как это:

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!'); 
} 

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

terminal

И в браузере:

alert

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

 Смежные вопросы

  • Нет связанных вопросов^_^