Partho Debnath
Partho Debnath

Reputation: 55

Django WSGI and ASGI

How can I run the ASGI and WSGI protocols separately in my Django project?

This is my project structure.

.
├── 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 file

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 file

from django.urls import path
from . import views

urlpatterns = [
    path("", views.index, name="index"),
]

wsgi.py file

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

application = get_wsgi_application()

chat/routing.py file

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 file

from chat.routing import websocket_urlpatterns

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

application = ProtocolTypeRouter(
    {
        "websocket": AllowedHostsOriginValidator(
            AuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
        ),
    }
)

After setting up all the configurations, I ran the HTTP and WebSocket servers on separate ports:

  1. Run the HTTP server (with Gunicorn):
     gunicorn config.wsgi:application --bind 0.0.0.0:8000
    
  2. Run the WebSocket server (with Daphne):
     daphne config.asgi:application --bind 0.0.0.0 --port 8001```
    
    
    

After running these servers, when I visit http://0.0.0.0:8000 in the browser, it works correctly. However, when I try to connect to the WebSocket using ws://0.0.0.0:8001/ws/chat/private-room/, it fails to connect. Can someone explain why it fails to connect? In the asgi.py file, I do not want to use "http": get_asgi_application() in the ProtocolTypeRouter mapping like:

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)),
        ),
    }
)

Upvotes: 0

Views: 41

Answers (1)

72mins
72mins

Reputation: 90

I am pretty sure your routing.py file is supposed to look something like this:

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,
        )
})

You are missing the ProtocolTypeRouter and the URLRouter that are wrapping them.

Also, why wouldn't you want to do this:

In the asgi.py file, I do not want to use "http": get_asgi_application() in the ProtocolTypeRouter mapping..

This allows you to run both your WSGI and ASGI applications at the same time. You do not have to run gunicorn or daphne when working locally at all.

With this configuration, you should be able to run both the WSGI and ASGI applications at the same time just using the built-in django server by running:

python manage.py runserver

Upvotes: 0

Related Questions