WebSocket connection to 'wss://example.com/wss/' failed in Django Channels

WebSocket connection to 'wss://example.com/wss/' failed in Django Channels
python
Ethan Jackson

I'm trying to set up a WebSocket connection using Django Channels in my Django project. However, I keep encountering an error when trying to connect from the frontend JavaScript. The error message in the browser console is:

WebSocket connection to 'wss://example.com/wss/' failed

Here is my project structure:

project/ ├── myproject/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ ├── wsgi.py │ ├── asgi.py ├── myapp/ │ ├── __init__.py │ ├── views.py │ ├── urls.py │ ├── consumers.py │ ├── routing.py │ ├── templates/ │ ├── index.html ├── manage.py ├── passenger_wsgi.py ├── requirements.txt

My settings.py includes:

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'channels', ] ASGI_APPLICATION = 'myproject.asgi.application' CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels.layers.InMemoryChannelLayer', }, }

The asgi.py file is configured as follows:

import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack import myapp.routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( myapp.routing.websocket_urlpatterns ) ), })

My routing.py:

from django.urls import path from . import consumers websocket_urlpatterns = [ path('wss/', consumers.LoadConsumer.as_asgi()), ]

The consumer class in consumers.py:

from channels.generic.websocket import AsyncWebsocketConsumer class LoadConsumer(AsyncWebsocketConsumer): async def connect(self): await self.accept() async def disconnect(self, close_code): pass async def receive(self, text_data): pass

And here is the JavaScript code for the WebSocket connection:

const socket = new WebSocket('wss://example.com/wss/'); socket.onopen = function(event) { console.log("WebSocket is open now."); }; socket.onmessage = function(event) { console.log("WebSocket message received:", event); }; socket.onclose = function(event) { console.log("Connection closed"); }; socket.onerror = function(error) { console.log("WebSocket Error:", error); };

enter image description here

Edit

from django.urls import re_path from . import consumers websocket_urlpatterns = [ re_path('ws/', consumers.LoadConsumer.as_asgi()), ]

Answer

I found it! Or at least I think I did. Starting in Django 2.0, path() was introduced as a simpler way to write URL paths in Django. Unfortunately this doesn’t provide everything Django Channels needs to provide routing. In their own words:

Note we use re_path() due to limitations in URLRouter.

I have no idea what limitations they encountered but it is plausible because even the Django team acknowledges that path() is a simpler interface while re_path() is for finer control and more versatility.

Most people actually make this mistake too so you are not alone in this. [1]

Change your code from using path() to using re_path() and you will be fine.


[1] Here [github] is one such case posited in the answer.

Related Articles