Daphne服务器无法与HTTPS

时间:2016-07-16 20:13:18

标签: python django websocket openshift django-channels

我正在Openshift云上部署Django项目。该项目使用channels和Websockets使其异步工作。问题是我无法成功地将浏览器中的websockets连接到我在服务器端运行的Daphne Server。

我正在使用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!');
}

请注意,由于this文档,我在Daphne设置和WebSockets设置中使用端口8443。此外,Daphne绑定到OPENSHIFT_HOST地址,因为在Openshift中无法将其绑定到0.0.0.0(权限问题)

输出如下:

first

second

third

客户端的一切看起来都不错,但如果你还记得,在 consumers.py 我有这个:

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

所以在我的终端中,服务器应该打印出类似:“接收:来自”,但事实并非如此。我在这里缺少什么?

tl; dr:客户端websocket看起来已正确连接但服务器没有打印出确认消息的消息。

1 个答案:

答案 0 :(得分:4)

我设法让它发挥作用。问题似乎与端口转发有关,这使我无法通过openshift云上的apache服务器将websockets连接到我的daphne服务器。

解决这个问题:

1)使用django项目的默认盒式磁带我无法修改apache conf文件甚至更新apache以安装mod_proxy_wstunnel来支持websockets所以我决定更改它。 此外,mod_proxy_wstunnel适用于apache 2.4,但默认盒式磁带使用2.2。

渠道文档,建议使用nginx。所以我发现cartridge允许我和uwsgi和django一起使用它。

我按照那个仓库中的说明进行操作,但是在推送我的代码之前,我调整了一些动作钩子以获得这些包的最新版本,并用我的替换了示例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 &
...

所以daphne正在监听$ 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

所以我知道这是有效的。我希望这可以帮助别人,除了我。