Джанго WSGI и ASGI
Как я могу запустить протоколы ASGI и WSGI отдельно в моем проекте Django?
Это структура моего проекта.
.
├── chat # <== my app name
│ ├── apps.py
│ ├── consumers.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── __init__.py
│ ├── models.py
│ ├── routing.py
│ ├── templates
│ │ └── chat
│ │ ├── index.html
│ │ └── room.html
│ ├── urls.py
│ └── views.py
├── config # <== project configuration
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
setting.py файл
ALLOWED_HOSTS = ["*"]
INSTALLED_APPS = [
"daphne",
...,
...,
"chat",
]
# for HTTP protocal
WSGI_APPLICATION = "config.wsgi.application"
# for Websocket protocal
ASGI_APPLICATION = "config.asgi.application"
chat/urls.py файл
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
wsgi.py файл
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_wsgi_application()
chat/routing.py файл
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r"ws/chat/(?P<room_name>\w+)/$", consumers.ChatConsumer.as_asgi()),
]
asgi.py файл
from chat.routing import websocket_urlpatterns
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = ProtocolTypeRouter(
{
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
),
}
)
После настройки всех конфигураций я запустил серверы HTTP и WebSocket на разных портах:
- Запустите HTTP-сервер (с помощью Gunicorn):
gunicorn config.wsgi:application --bind 0.0.0.0:8000
- Запустите сервер WebSocket (с помощью Daphne):
daphne config.asgi:application --bind 0.0.0.0 --port 8001```
После запуска этих серверов, когда я захожу на http://0.0.0.0:8000 в браузере, все работает корректно. Однако, когда я пытаюсь подключиться к WebSocket с помощью ws://0.0.0.0:8001/ws/chat/private-room/, подключиться не удается. Кто-нибудь может объяснить, почему не удается подключиться? В файле asgi.py я не хочу использовать "http": get_asgi_application() при сопоставлении типа протокола с маршрутизатором, например:
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = ProtocolTypeRouter(
{
"http": get_asgi_application(), # i do not want to use this.
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
),
}
)
Я почти уверен, что ваш routing.py файл должен выглядеть примерно так:
from channels.routing import ProtocolTypeRouter, URLRouter
from django.urls import path
from apps.chat_app.consumers import ChatConsumer, ChannelConsumer, NotificationConsumer
websocket_urlpatterns = [
path('chat/<int:id>/<int:curr>/', ChatConsumer.as_asgi()),
]
application = ProtocolTypeRouter({
'websocket':
URLRouter(
websocket_urlpatterns,
)
})
Вам не хватает маршрутизатора типа протокола и URLRouter, которые их обертывают.
Кроме того, почему бы вам не захотеть сделать это:
В файле asgi.py Я не хочу использовать "http": get_asgi_application() при сопоставлении типа протокола с маршрутизатором..
Это позволяет запускать приложения WSGI и ASGI одновременно. При локальной работе вам вообще не нужно запускать gunicorn или daphne.
При такой конфигурации вы сможете запускать приложения WSGI и OSGI одновременно, просто используя встроенный сервер django, выполнив:
python manage.py runserver