Websockets не работают с каналами Django после развертывания

Я пытаюсь развернуть свой проект Django, но столкнулся с некоторыми трудностями.

Все прекрасно работает на локальной машине.

Я использую Django + nginx + uvicorn (запущенный супервизором). Также, я получил свой SSL сертификат в использовании.

Когда я пытаюсь подключиться к websocket (/ws) через загрузку страницы и заставить мои js файлы работать, я получаю сообщение в консоли:

WebSocket connection to 'wss://example.com/ws/' failed

Вот моя конфигурация nginx

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

server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}
server {
    listen 443 ssl;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    server_name example.com;
    client_max_body_size 100M;

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;
    location /ws/ {
                proxy_pass https://uvicorn/ws;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection $connection_upgrade;
                proxy_http_version 1.1;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_intercept_errors on;
                proxy_redirect off;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-NginX-Proxy true;
                proxy_ssl_session_reuse off;
    }

    location /static/ {
        root /root/server/social;
        expires 1d;
    }

    location /media/ {
        root /root/server/social;
        expires 1d;
    }

    location / {
        proxy_pass https://uvicorn;
        proxy_set_header Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

upstream uvicorn {
        server unix:/tmp/uvicorn.sock;
}

И конфигурация супервизора

[program:django]
command = /root/server/social/venv/bin/python -m uvicorn myproject.asgi:application --uds /tmp/uvicorn.sock --ssl-keyfile=/etc/letsencrypt/live/mysite.com/privkey.pem --ssl-certfile=/etc/letsencrypt/live/mysite.com/fullchain.pem
directory = /root/server/social
stderr_logfile=/var/log/long.err.log
stdout_logfile=/var/log/long.out.log
autostart=true
autorestart=true

Когда все готово, я запускаю nginx: service nginx restart. Я не получаю никаких ошибок. После этого я запускаю service supervisor restart. И вот в чем дело. Если никто не использует сайт, в моих логах (/var/log/long.err.log) я не получаю ошибок:

INFO:     connection closed
INFO:     Shutting down
INFO:     Finished server process [606]
INFO:     Started server process [660]
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
INFO:     Uvicorn running on unix socket /tmp/uvicorn.sock (Press CTRL+C to quit)

Но если кто-то использует веб-сайт и активирует websocket, я получаю:

File "/root/server/social/venv/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 1216, in write_close_frame
    await self.write_frame(True, OP_CLOSE, data, _state=State.CLOSING)
  File "/root/server/social/venv/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 1189, in write_frame
    await self.drain()
  File "/root/server/social/venv/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 1178, in drain
    await self.ensure_open()
  File "/root/server/social/venv/lib/python3.9/site-packages/websockets/legacy/protocol.py", line 921, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: sent 1000 (OK); no close frame received
INFO:     connection closed


Вот все, что связано с websockets в структуре проекта, если нужно:

routing.py

from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path(r"ws/messenger/", consumers.ChatConsumer.as_asgi()),
    re_path(r"ws/profile/", consumers.ProfileConsumer.as_asgi()),
    re_path(r"ws/like/", consumers.LikeConsumer.as_asgi())
]

asgi.py

import os

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

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

application = ProtocolTypeRouter({
    "http":get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(messenger.routing.websocket_urlpatterns)

    )
})

consumers.py

import json
from channels.generic.websocket import WebsocketConsumer
from profile.models import User, Message, Chat, Publication
from asgiref.sync import async_to_sync
from datetime import datetime

group_members = []


class ChatConsumer(WebsocketConsumer):
    ...


class ProfileConsumer(WebsocketConsumer):
    ...


class LikeConsumer(WebsocketConsumer):
    ...


Я могу предоставить больше информации, если это необходимо. Надеюсь, ваш отзыв поможет мне!

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