Какой правильный файл / требования для heroku с каналами django?

tl; dr - приложение каналов django запускается локально с сервером manage.py, но не на heroku.

Я новичок в каналах django - пытаюсь развернуть очень простое приложение django, используя каналы на heroku. Изначально я построил проект с использованием стандартного руководства по опросам django и развернул его на heroku. . Затем я добавил приложение чата, используя руководство по каналам django. Удалось заставить это работать нормально локально, используя докер для запуска сервера Redis, как они предлагали, и «python manage.py runserver».

Я застреваю, пытаясь развернуть это на heroku или запустить его локально, используя heroku local. Я уже добавил надстройку redis в heroku и изменил settings.py, чтобы он указывал на переменную окружения REDIS_URL. Я также изменил свой шаблон, чтобы использовать wss, если это необходимо (я считаю, что это необходимо для heroku):

var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
        var target = ws_scheme + '://'
        + window.location.host
        + '/ws/chat/'
        + roomName
        + '/';
        const chatSocket = new WebSocket(
          target
        );
...

Таким образом, я прихожу к выводу, что проблема связана с файлом procfile. Я не уверен, какие есть инструкции по использованию. В первоначальном руководстве по опросам использовалось:

web: gunicorn gettingstarted.wsgi --log-file -

Если я просто использую этот «heroku local», все будет нормально, и развертывание будет работать нормально, но когда я пытаюсь отправить сообщение чата, оно ничего не делает и показывает 404 в консоли. Я знаю, что мне нужно изменить его, чтобы использовать сервер asgi вместо Gunicorn. нашел это руководство по развертыванию приложения с каналами на heroku, в котором использовались:

web: daphne chat.asgi:channel_layer --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker -v2

Я пробовал это, но тут я застрял. Вот что я получаю, когда запускаю heroku local:

krishnas-air:python-getting-started Krishna$ heroku local
[OKAY] Loaded ENV .env File as KEY=VALUE Format
6:46:50 PM worker.1 |  Traceback (most recent call last):
6:46:50 PM worker.1 |    File "manage.py", line 8, in <module>
6:46:50 PM worker.1 |      from django.core.management import execute_from_command_line
6:46:50 PM worker.1 |  ImportError: No module named django.core.management
[DONE] Killing all processes with signal  SIGINT
6:46:50 PM worker.1 Exited with exit code null
6:46:50 PM web.1    |  Traceback (most recent call last):
6:46:50 PM web.1    |    File "/usr/local/bin/daphne", line 5, in <module>
6:46:50 PM web.1    |      from daphne.cli import CommandLineInterface
6:46:50 PM web.1    |    File "/usr/local/lib/python3.7/site-packages/daphne/cli.py", line 1, in <module>
6:46:50 PM web.1    |      import argparse
6:46:50 PM web.1    |    File "<frozen importlib._bootstrap>", line 983, in _find_and_load
6:46:50 PM web.1    |    File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
6:46:50 PM web.1    |    File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
6:46:50 PM web.1    |    File "<frozen importlib._bootstrap_external>", line 724, in exec_module
6:46:50 PM web.1    |    File "<frozen importlib._bootstrap_external>", line 857, in get_code
6:46:50 PM web.1    |    File "<frozen importlib._bootstrap_external>", line 525, in _compile_bytecode
6:46:50 PM web.1    |  KeyboardInterrupt
6:46:50 PM web.1    Exited with exit code null

Сообщение об ошибке импорта заставило меня подумать, что в моем файле requirements.txt что-то не хватает, поэтому я включил его сюда для справки:

django
gunicorn
django-heroku
requests
channels
channels_redis
asgi_redis
asgiref
daphne
redis
gevent
gevent-websocket
greenlet

Спасибо за любую помощь!


person Krishna    schedule 01.05.2020    source источник
comment
Можете ли вы показать содержимое вашего chat.asgi файла?   -  person Ken4scholars    schedule 10.05.2020


Ответы (1)


Я только что выяснил очень похожую проблему. Прежде всего, хотя эти документы не относятся к Heroku, их необходимо прочитать.

Я думаю, проблема в том, что Heroku направляет ws:// запросы через WSGI, а не через ASGI. Итак, первый шаг - создать asgi.py файл в той же папке, что и wsgi.py, примерно так:

import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dropdjango.settings")
django.setup()
application = get_default_application()

Затем в Procfile определите dynos для web worker:

web: daphne <my-web-app>.asgi:application --port $PORT --bind 0.0.0.0 -v2
worker: python manage.py runworker channel_layer -v2

Если дино еще не существует в Heroku, создайте их с помощью Heroku CLI. В моем случае дино web уже существовал, поэтому я создал только дино worker:

heroku ps:scale worker=1:free -a <your-heroku-app-name>

Наконец, дважды проверьте свой settings.py, чтобы убедиться, что у вас есть:

ASGI_APPLICATION="<my-web-app>.routing.application"
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {"hosts": [os.environ.get("REDIS_URL", "redis://localhost:6379")]},
    },
}

Предупреждение: все ваши запросы будут выполняться через daphne. Я читал о предостережениях, но еще не сталкивался с ними.

person Ivan Figueroa    schedule 23.07.2020
comment
У меня все работает нормально локально (у меня были такие же настройки в других местах в отношении ASGI), но меня просто интересовала строка кода worker:. Проголосую за это, если это сработает. Я имею в виду, что остальное из того, что вы упомянули, имеет смысл, потому что CHANNEL_LAYERS уже объявлен в настройках, и worker вызывает его. - person Roast Biter; 08.09.2020
comment
Всем привет. Конфигурационный dict CHANEL_LAYERS просто определяет redis как бэкэнд. channel_layer в файле рабочего процесса (Procfile) является аргументом для функции python manage.py runworker. Этот аргумент представляет имя канала, который рабочий будет слушать. github.com/django/channels/blob/ мастер / каналы / управление / Вы можете увидеть в - person Ivan Figueroa; 10.09.2020
comment
просто любопытно, что -v2 делает здесь, в файле proc? - person Roast Biter; 10.09.2020
comment
как насчет переменной окружения $ PORT? Разве запускать это в производстве не является предпочтительным? - person Roast Biter; 14.09.2020