Отправка запросов от одного uwsgi к другому экземпляру uwsgi с запущенными каналами Django - PullRequest
0 голосов
/ 22 марта 2019

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

"Веб-сервер выполняет задачу отправки обычных запросов одному экземпляру uWSGI, а запросы WebSocket - другому"

Теперь у меня запущены два экземпляра uwsgi. Вот как я бегу оба.

Этот uwsgi обрабатывает обычные запросы сайта django

uwsgi --virtualenv /home/ec2-user/MyProjVenv --socket /home/ec2-user/MyProjVenv/MyProjWeb/site1.socket --chmod-socket=777 --buffer-size=32768 --workers=5 --master --module main.wsgi

Этот uwsgi обрабатывает запросы websocket

uwsgi --virtualenv /home/ec2-user/MyProjVenv --http-socket /home/ec2-user/MyProjVenv/MyProjWeb/web.socket --gevent 1000 --http-websockets --workers=2 --master --chmod-socket=777  --module main.wsgi_websocket

Теперь websocket uwsgi запускает main.wsgi_websocket

Код для main.wsgi_websocket one - это

import os
import gevent.socket
import redis.connection
redis.connection.socket = gevent.socket
os.environ.update(DJANGO_SETTINGS_MODULE='main.settings')
from ws4redis.uwsgi_runserver import uWSGIWebsocketServer
application = uWSGIWebsocketServer()

Теперь, после вращения двух экземпляров uwsgi, я могу получить доступ к веб-сайту в порядке. Экземпляр websocket uwsgi также получает данные, однако я не уверен, передает ли он эти данные в экземпляр uwsgi веб-сайта django, который в основном использует каналы django и имеет обработчики для отправки / получения функций. Я использую каналы Django здесь, и это конфигурация, которую я указал в моих настройках для каналов Django

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": {
            "hosts": [(redis_host, 6379)],
        },
       "ROUTING": "main.routing.channel_routing", 
    },
}

Канал маршрутизации это

channel_routing = [
    include("chat.routing.websocket_routing", path=r"^/chat/stream"),
    include("chat.routing.custom_routing"),
]

и это websocket_routing, который у меня есть

websocket_routing = [
    route("websocket.connect", ws_connect),


    # Called when WebSockets get sent a data frame
    route("websocket.receive", ws_receive),


    # Called when WebSockets disconnect
    route("websocket.disconnect", ws_disconnect),
]

Теперь проблема в том, что мой ws_receive никогда не вызывается. Если я тестирую на своем локальном компьютере с использованием ipaddress:8000/chat/stream, это прекрасно работает, однако я понятия не имею, почему мой прием не вызывается при использовании i padress/ws/. Я уверен, что мой другой экземпляр uwsgi получает эти данные, но я не знаю, как выяснить, передает ли он его другому экземпляру uwsgi на стороне djnago, и если это так, то почему мой получатель не вызывается? Любые предложения по этому вопросу определенно помогут

1 Ответ

0 голосов
/ 23 марта 2019

Мне было интересно об этом, когда я увидел ваш другой вопрос здесь Nginx с Дафни дают 502 Bad Gateway

Разделение проекта - хорошая идея. Я предполагаю, что эти два экземпляра работают за nginx (из вашего вышеупомянутого вопроса).

Итак, nginx должен решить, какой запрос к какому экземпляру? Вы можете сделать это, используя разные пути URL для каждого приложения channels и django.

Пример:

для приложения django: /whatever/whatever/... а для channels: /ws/whatever/...

Предположим, что ваш channels потребительский экземпляр находится на 8000.

Добавьте это к вашему nginx:

location /ws/ {
            proxy_pass http://0.0.0.0:8000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";

            proxy_redirect     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   X-Forwarded-Host $server_name;
        }

Таким образом, каким бы ни был ваш запрос, если URL начинается с /ws/, он используется любым экземпляром, работающим на порту 8000.

...