- Published on
Step-by-Step Breakdown of WebSocket Lifecycle in Django
- Authors

- Name
- Mehdi Akiki
Here's a step-by-step breakdown of the WebSocket lifecycle in Django, including which side (client or server) initiates each step and which methods are called:
Connection Establishment:
- Initiated by: Client
- Server-side method called:
connect() - What happens:
- The client sends a WebSocket handshake request to the server.
- Django's ASGI server receives this request and routes it to the appropriate consumer.
- The
connect()method of the consumer is called automatically by Django. - In the
connect()method, you typically set up the connection, possibly add the connection to groups, and then callself.accept()to complete the handshake.
Message Transmission (Client to Server):
- Initiated by: Client
- Server-side method called:
receive() - What happens:
- The client sends a WebSocket message.
- Django's ASGI server receives the message and passes it to the consumer.
- The
receive()method of the consumer is automatically called with the message data. - You process the message in the
receive()method.
Message Transmission (Server to Client):
- Initiated by: Server
- Server-side method called: Any method you define, often triggered by
receive()or external events - What happens:
- You call
self.send()within any consumer method to send a message to the client. - Django's ASGI server sends the WebSocket message to the client.
- You call
Group Message Broadcast:
- Initiated by: Server
- Server-side methods called:
group_send()followed by a custom method (e.g., chat_message()) - What happens:
- You call
self.channel_layer.group_send()to send a message to a group. - Django Channels broadcasts the message to all consumers in the group.
- For each consumer in the group, a custom method (specified in the type field of the message) is called.
- This custom method typically calls
self.send()to send the message to the connected client.
- You call
Connection Closure:
- Initiated by: Either Client or Server
- Server-side method called:
disconnect() - What happens:
- If client-initiated: The client sends a close frame.
- If server-initiated: You call
self.close()in your consumer. - Regardless of who initiates, Django calls the
disconnect()method of your consumer. - In the
disconnect()method, you typically clean up any resources, remove the connection from groups, etc.
Summary of WebSocket Lifecycle Methods in Django Consumers
| Step | Initiated by | Method in Consumer | Purpose |
|---|---|---|---|
| Connection Establishment | Client | connect() | Sets up the WebSocket connection. |
| Message (Client to Server) | Client | receive() | Processes a message from the client. |
| Message (Server to Client) | Server | send() | Sends a message to the client. |
| Group Message Broadcast | Server | group_send() + custom method | Broadcasts to group members. |
| Connection Closure | Either | disconnect() | Cleans up resources after disconnection. |
Diagram: Flow of WebSocket Messages in Django Channels
Here is how the websocket messages flow between the client and the server using Django Channels.
+--------------+ +----------------+ +---------------------+
| WebSocket | | ASGI Server | | Django Consumer |
| (Client) | <-----> | (Daphne/Uvicorn) | ----> | (MyConsumer) |
+--------------+ +----------------+ +---------------------+
| | |
| 1. WebSocket | 2. ASGI routing | 3. Message processing
| message | matches consumer | and response
| | |
+--------------------> Consumer receives +<----------------
Example Code: WebSocket Consumer
Here’s a complete WebSocket consumer example that demonstrates each step in the lifecycle:
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = f'chat_{self.room_name}'
# Join room group
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept() # Complete the WebSocket handshake
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# Send message to room group
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
async def chat_message(self, event):
message = event['message']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message
}))
In this example:
connect()is called when a client initiates a connection.receive()is called when a message is received from the client.chat_message()is a custom method called when a message is received from the channel layer (group broadcast).disconnect()is called when the connection is closed by either side.
Remember, Django (the server) calls these methods in response to client actions or internal events. You don't call these methods directly in your code; instead, you define them, and Django's WebSocket handling system invokes them at the appropriate times.
Conclusion
Understanding the WebSocket lifecycle in Django Channels helps you build real-time applications that require bidirectional communication between a client and server. Each step in the lifecycle, from connection establishment to message processing and connection closure, follows a structured event-driven model that leverages Django’s ASGI layer for asynchronous communication. By defining methods like connect(), receive(), and disconnect(), you control how your server interacts with WebSocket clients.
Whether you are building a chat application, real-time dashboard, or multiplayer game, mastering these lifecycle methods ensures your application handles WebSocket connections efficiently and correctly.
I build and scale reliable production systems. Open to full-time and freelance work with U.S.-based teams that value ownership and execution.
Got something in mind?
Book a Discovery Call