Reputation: 55
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:
gunicorn config.wsgi:application --bind 0.0.0.0:8000
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
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