Django/Daphne/Nginx Websockets не подключается
Я использую django с daphne и nginx для запуска моих вебсокет. Все работало отлично в течение нескольких месяцев в продакшене, однако пару дней назад мои вебсокеты не подключались, говоря "WebSocket соединение с 'wss://mydomain:8001/clips/509/' не удалось: ". Я проверил журналы сервера, и вот что вышло
2022-04-07 16:57:22,970 ERROR [Failure instance: Traceback: <class 'AttributeError'>: 'NoneType' object has no attribute 'replace'
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/autobahn/websocket/protocol.py:2839:processHandshake
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/txaio/tx.py:366:as_future
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/twisted/internet/defer.py:151:maybeDeferred
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/daphne/ws_protocol.py:72:onConnect
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: --- <exception caught here> ---
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/twisted/internet/defer.py:151:maybeDeferred
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/daphne/server.py:200:create_application
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/channels/routing.py:54:__call__
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/channels/security/websocket.py:35:__call__
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/channels/security/websocket.py:53:valid_origin
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/channels/security/websocket.py:72:validate_origin
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/channels/security/websocket.py:73:<genexpr>
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /home/django/Odyssey/venv/lib/python3.8/site-packages/channels/security/websocket.py:97:match_allowed_origin
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /usr/lib/python3.8/urllib/parse.py:376:urlparse
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: /usr/lib/python3.8/urllib/parse.py:430:urlsplit
Apr 07 16:57:22 ubuntu-s-1vcpu-1gb-nyc1-01 python[1276]: ]
Я не понимаю, почему это произошло внезапно, может быть, зависимость была обновлена или удалена? Любые идеи будут полезны, потому что я безумно застрял.
Я решил эту проблему, отредактировав файл redis.service
nano /etc/systemd/system/redis.service
ExecStop=/bin/kill -s TERM $MAINPID
ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/redis/redis.pid"
then type
sudo systemctl daemon-reload
sudo systemctl enable redis-server
sudo systemctl restart redis.service
Это происходит потому, что исправление в urllib3. AllowedHostsOriginValidator сломался. Я решил эту проблему, отредактировав свой файл asgi.py.
Я изменил определение моего "приложения" следующим образом:
import os
from .wsgi import *
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault(
'DJANGO_SETTINGS_MODULE',
'manager.settings.production'
)
from .routing import websocket_urlpatterns
application = ProtocolTypeRouter({
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
)
)
})
на это:
import os
from .wsgi import *
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
os.environ.setdefault(
'DJANGO_SETTINGS_MODULE',
'manager.settings.production'
)
from .routing import websocket_urlpatterns
application = ProtocolTypeRouter({
"websocket": AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
)
})
Больше информации здесь: https://githubhot.com/repo/django/channels/issues/1716