运行 nginx 反向代理后面的 daphne 协议升级总是路由到 http 而不是 websocket

Running daphne behind nginx reverse proxy with protocol upgrade always routes to http instead of websocket

我正在尝试在 Nginx 反向代理服务器后面部署 django 通道驱动的通知应用程序以仅服务于 websocket 通信,同时设置 Nginx + uWSGI 以服务于 django 应用程序。

当 运行 使用 python manage.py runserver --noasgi + daphne -p 8000 myproject.asgi:applicationpython manage.py runserver 使用 daphne 处理所有内部请求时,应用程序在我的本地机器上无缝运行。

问题:

所有 websocket 请求都被路由到 http 协议类型而不是 websocket 协议类型并且它 returns WebSocket connection to 'ws://ip_address/ws/' failed: Error during WebSocket handshake: Unexpected response code: 404

已安装的软件包:

Django==2.0.3
channels==2.0.2
channels-redis==2.1.1
daphne==2.1.0
asgiref==2.3.0
Twisted==17.9.0
aioredis==1.0.0
autobahn==18.4.1

环境:

Ubuntu - 16.04
Nginx - 1.12.0

升级请求的Nginx配置:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

# the upstream component nginx needs to connect to websocket requests
upstream websocket {
    server unix:/path/to/my/app/daphne.sock;
}

# configuration of the server
server {

        # the port your site will be served on
        listen      80;

        # the domain name it will serve for
        server_name ip_address;
        charset     utf-8;

       # Sending all non-media requests for websockets to the Daphne server.
        location /ws/ {
            proxy_pass http://websocket;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
        }

}

routing.py

from django.conf.urls import url

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from myapp import consumers

application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter([
            url(r'^ws/$', consumers.MyConsumer),
        ])
    ),
})

达芙妮日志:

None - - [TimeStamp] "GET /ws/" 404 3
None - - [TimeStamp] "GET /ws/" 404 3
None - - [TimeStamp] "GET /ws/" 404 3

如果需要任何其他帮助,请告诉我。

P.S: 我在两台服务器上部署了同一个应用程序(配置和环境都和上面一样),结果一样。

最后我发现罪魁祸首是我公司的防火墙,当通过 http 访问应用程序时,它正在剥离升级 headers。所以在将 http 升级到 https 后,它开始按预期工作。