Использование каналов Django с apache2 и daphne (не удалось подключиться через веббсокет к «wss://MYDOMAIN/ws/main/» :)

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

Я знаю, что по этой теме были похожие вопросы, и я изо всех сил пытался решить эту проблему, используя их, но мне не повезло.

Я использую apache2 для обслуживания приложения и пытаюсь перенаправить любые запросы веб-сокетов daphne. Веб-страница загружается без проблем, но в консоли браузера я получаю сообщение об ошибке

(не удалось подключиться через веббсокет к «wss://MYDOMAIN/ws/main/» :)

Здесь нам мой apache conf

<VirtualHost *:444>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com
        ServerName myDomain
        ServerAdmin admin
        DocumentRoot /var/www/thomasmichaelides/public_html



       # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
       # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".

        # Enable Websocket connections on port 8888
        RewriteEngine on
        RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
        RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
        RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]

        Alias /static /home/atwebapps/arduinoDjango/static
       <Directory /home/atwebapps/arduinoDjango/static>
               Require all granted
       </Directory>

       <Directory /home/atwebapps/arduinoDjango/arduinoDjango>
               <Files wsgi.py>
                       Require all granted
               </Files>
       </Directory>
       WSGIScriptAlias / /home/atwebapps/arduinoDjango/arduinoDjango/wsgi.py
       WSGIDaemonProcess arduinoApp python-path=/home/atwebapps/arduinoDjango python-home=/home/atwebapps/arduinoDjango/venv
       WSGIProcessGroup arduinoApp





SSLCertificateFile /etc/letsencrypt/live/mydomain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mydomain/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

а вот моя daphne.service

    [Unit]
Description=WebSocket Daphne Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/atwebapps/arduinoDjango
ExecStart=/home/atwebapps/arduinoDjango/venv/bin/python /home/atwebapps/arduinoDjango/venv/bin/daphne -b 0.0.0.0 -p 8001 arduinoDjango.asgi:application
Restart=on-failure

[Install]
WantedBy=multi-user.target

Есть ли что-нибудь очевидное в отношении того, почему соединение ws продолжает терпеть неудачу?

Я также добавлю свой файл asgi.py и файл settings.py.

asgi.py

"""
ASGI config for arduinoDjango project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

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

application = get_asgi_application()

settings.py (вещи, связанные с каналами)

INSTALLED_APPS = [
    'main.apps.MainConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'channels',
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

WSGI_APPLICATION = 'arduinoDjango.wsgi.application'
ASGI_APPLICATION = 'arduinoDjango.routing.application'
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

use_websockets = True

Любое понимание этого будет высоко оценено

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы близки, но помните, что служба daphne на сервере запускает несколько экземпляров или приложений Python асинхронно. Он работает между кодом apache и кодом сервера django, перенаправляя веб-трафик туда, куда ему нужно.

Поэтому указывать WSGIScriptAliasWSGIDaemonProcess или WSGIProcessGroup не нужно. Вам нужно указать, на какие порты мы перенаправляем трафик. Кажется, вы справились с http трафиком; но хитрость с веб-сокетами здесь заключается в том, что вы должны помнить, что наш браузер должен подключаться через Интернет с помощью wss, в отличие от веб-сокета, который фактически работает локально на нашем сервере. Мы можем решить эту проблему, перенаправив весь wss веб-трафик на локальный порт ws, где работает веб-сокет.

Рассмотрим следующую конфигурацию Apache с SSL, которая требуется на производственном уровне.

    ...
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
    RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
    RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]
    ProxyPass /wss/ wss://127.0.0.1:8001/
    ProxyPassReverse /wss/ wss://127.0.0.1:8001/
    ...
    SSLEngine on
    SSLCertificateFile /etc/ssl/certificate.crt
    SSLCertificateKeyFile /etc/ssl/private/private.key
    SSLCertificateChainFile /etc/ssl/ca_bundle.crt
    ...

Затем вам нужно запустить сервер, поэтому на производственном уровне вам понадобится контейнер Docker или какая-то методология для поддержания работы кода. Обязательно измените порт на рабочем уровне, чтобы он соответствовал вашей конфигурации apache.

daphne -b 0.0.0.0 -p 8001 django_project.asgi:application // Local Development Level
daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:application // Production Level

Привет Грейсен, спасибо за ваш вклад. Я изменил свой файл конфигурации apache в соответствии с вашим, а также удалил WSGIScriptAlias, WSGIDaemonProcess и WSGIProcessGroup. Однако теперь я просто получаю пустую веб-страницу: не уверен, что это положительное или отрицательное, ха-ха

Thomas Michaelides 19.04.2023 13:38

Вы тщательно проверили зависимости вашего пакета от вашей версии Python, используя pypi.org? В моем случае Python 3.6.9, который я не рекомендую использовать для этой установки, мне пришлось установить определенные версии daphne и каналов. Несмотря на то, что они автоматически устанавливаются с правильными зависимостями, у меня были пакеты, которые должны были работать с определенной версией python, которые не взаимодействовали друг с другом должным образом. Особенно беспокоит Дафна. Убедитесь, что ваши каналы не имеют последней версии для вашего Python (стабильной), и откатите версию daphne за версией.

Gracen Ownby 19.04.2023 20:22

Также вам нужно найти, где Дафна ведет журнал, и посмотреть, появляется ли ошибка при переходе на веб-страницу, но, вероятно, это исключение в Дафне или каналах.

Gracen Ownby 19.04.2023 20:25

Другие вопросы по теме