【问题标题】:Uvicorn + Django + NGinx - Error 404 while handling websocketsUvicorn + Django + NGinx - 处理 websocket 时出现错误 404
【发布时间】:2021-09-18 04:10:36
【问题描述】:

我正在使用 Nginx 和 Uvicorn 设置服务器来运行带有 websockets 的 Django 应用程序。

正常的 http 请求一切顺利,我可以获取我的网页,但我的 websockets 握手总是以 404 错误结束。

使用 runserver 一切顺利。

这是我的 asgi.py 文件

import os
import django
django.setup()

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import MYAPP.routing
import Stressing.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MYAPP.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack( URLRouter( Stressing.routing.websocket_urlpatterns ) ),
    # Just HTTP for now. (We can add other protocols later.)
})

我的设置.py

ASGI_APPLICATION = 'MYAPP.asgi.application'

redis_host = os.environ.get('REDIS_HOST', '127.0.0.1')

CHANNEL_LAYERS = {
    'default': {
        'CONFIG': {
            'hosts': [(redis_host, 6379)],
        },
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
    },
}

我的 nginx 配置文件

server {
    listen 80;
    server_name MYAPP.box 10.42.0.1;
    
    
    location = /favicon.ico { access_log off; log_not_found off; }
    location ~ ^/static {
        autoindex on;
        root /home/MYAPP;
    }

    location ~ ^/ {
        include proxy_params;
        proxy_pass http://unix:/home/MYAPP/MYAPP.sock;
    }
    location @proxy_to_app {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_buffering off;
        
        proxy_pass http://unix:/home/MYAPP/MYAPP.sock;
    }
    location ~ ^/ws/ {
        proxy_pass http://unix:/home/MYAPP/MYAPP.sock;
        proxy_http_version 1.1;
        proxy_redirect off;
        proxy_buffering off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

正如我在 gunicorn 日志中看到的那样,请求似乎到达了套接字

not found /ws/0

有人知道问题的根源吗?

【问题讨论】:

  • 原来我使用的是 uvicorn 而不是 uvicorn[standard] 才能使用 websockets。安装后(相当复杂,因为 uvloop 的编译在内存中是贪婪的,我需要创建一个交换文件),我实际上仍然有同样的问题。 “未找到:/ws/0/”我还有信息“ASGI 'lifespan' 协议似乎不受支持”。我不确定这是否会产生影响

标签: django nginx websocket gunicorn uvicorn


【解决方案1】:

我已经从我的 Nginx 文件中删除了正则表达式,它现在可以工作了

location ~ ^/ {
...
location ~ ^/ws/

成为

location / {
...
location /ws/

这样就解决了。但如果有人能解释一下它的背景呢? 我认为 Nginx 总是优先考虑最具体的路径。它只在没有正则表达式的情况下工作吗? (我想没有办法确定哪个正则表达式更具体?!)

【讨论】:

    猜你喜欢
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 2020-09-03
    • 2016-05-22
    • 2018-12-04
    相关资源
    最近更新 更多