Nginx websocket не работает с каналами django (url не найден)

Я хочу реализовать приложение для чата в реальном времени, используя каналы django и redis. Все работает в разработке, но в продакшене я не могу добиться правильной настройки websockets.

У меня есть gunicorn, работающий как сервер для обработки http запросов, и теперь я пытаюсь настроить daphne для обработки websockets.

Nginx корректно проксирует все http запросы на gunicorn и поэтому все запросы, использующие только http, работают нормально.

Однако, когда я пытаюсь подключиться к вебсокету в моем фронтенде, daphne говорит, что url не найден.

То же самое происходит, когда я использую uvicorn в качестве asgi сервера вместо daphne. Также, когда я позволяю daphne обрабатывать http и websocket запросы, daphne не имеет проблем с http, но не может найти урлы websocket.


Моя установка следующая:

settings.py

WSGI_APPLICATION = 'config.wsgi.application'
ASGI_APPLICATION = 'config.asgi.application'

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

asgi.py

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

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.production')

django_asgi_app = get_asgi_application()

import chat.routing

application = ProtocolTypeRouter({
    'http': django_asgi_app,
    'websocket': AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
})

routing.py

from django.conf.urls import url

from .consumers import ChatConsumer


websocket_urlpatterns = [
    url(r"^ws/chat/$", ChatConsumer.as_asgi()),
]

(я пробовал тот же url с path, re_path и без regex)

frontend websocket connection

const chatSocket = new WebSocket(
    'wss://'
    + window.location.host
    + '/ws/chat'
);

nginx configuration

upstream entwicklung1 {
    server unix:/home/entwicklung1/entwicklung1/entwicklung1.sock;
}

upstream channels-backend {
    server unix:/home/entwicklung1/entwicklung1/daphne.sock;
}

server {
    listen 127.0.0.1:62118;
    server_name ___;

    ...

    location / {
        try_files $uri $uri/ @proxy;
    }

    location /ws {
        proxy_pass http://channels-backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location @proxy {
        ...
    }

    ...
}

Вот результат, когда я запускаю daphne с

daphne -u /home/entwicklung1/entwicklung1/daphne.sock config.asgi:application

и когда мой frontend пытается подключиться через websocket, daphne печатает

Not Found: /ws/chat
None - - [19/Aug/2021:10:39:04] "GET /ws/chat" 404

В access.log nginx показывает "GET /ws/chat HTTP/1.0" 404, что показывает, что каким-то образом websocket url интерпретируется как обычный http url (который, очевидно, не существует ни в одном из моих urls.py).


Мне кажется, что nginx или daphne ищет http url вместо websocket url.

Правильная ли у меня конфигурация nginx? Есть идеи?

Заранее спасибо.

Вернуться на верх