Posted under » Django on 14 July 2026
Continue from part 1.
When Django accepts an HTTP request, it consults the root URLconf to lookup a view function, and then calls the view function to handle the request. Similarly, when Channels accepts a WebSocket connection, it consults the root routing configuration to lookup a consumer, and then calls various functions on the consumer to handle events from the connection.
It is good practice to use a common path prefix like /ws/ to distinguish WebSocket connections from ordinary HTTP connections because it will make deploying Channels to a production environment in certain configurations easier.
Put the following code in chat/routing.py:
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r"ws/socket-server/$", consumers.ChatConsumer.as_asgi()),
]
We call the as_asgi() classmethod in order to get an ASGI application that will instantiate an instance of our consumer for each user-connection. This is similar to Django’s as_view(), which plays the same role for per-request Django view instances.
# chat/consumers.py. A Python class on the server side that acts similarly to Django Views, but specifically handles the WebSocket lifecycle (`connect`, `receive`, `disconnect`, and `broadcast`).
import json
from channels.generic.websocket import WebsocketConsumer
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.accept()
def disconnect(self, close_code):
pass
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json["message"]
self.send(text_data=json.dumps({"message": message}))
So views -> consumers and url -> routing.
Continue to part 3.