Джанго 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 на разных портах:

  1. Запустите HTTP-сервер (с помощью Gunicorn):
     gunicorn config.wsgi:application --bind 0.0.0.0:8000
    
  2. Запустите сервер 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
Вернуться на верх