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? Есть идеи?
Заранее спасибо.