Django Channels extends Django beyond HTTP to handle WebSockets, chat protocols, and IoT. It brings real-time capabilities while maintaining Django's synchronous, easy-to-understand programming model. At ZIRA Software, Channels powers our real-time Django applications.
Installation
pip install channels channels-redis
# settings.py
INSTALLED_APPS = [
'channels',
# ...
]
ASGI_APPLICATION = 'myproject.asgi.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [('127.0.0.1', 6379)],
},
},
}
ASGI Configuration
# myproject/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import chat.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = ProtocolTypeRouter({
'http': get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
WebSocket Consumer
# chat/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
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()
# Send join notification
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'user_join',
'username': self.scope['user'].username,
}
)
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):
data = json.loads(text_data)
message = data['message']
# Save to database
await self.save_message(message)
# Send to room group
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'username': self.scope['user'].username,
}
)
async def chat_message(self, event):
# Send message to WebSocket
await self.send(text_data=json.dumps({
'type': 'message',
'message': event['message'],
'username': event['username'],
}))
async def user_join(self, event):
await self.send(text_data=json.dumps({
'type': 'join',
'username': event['username'],
}))
@database_sync_to_async
def save_message(self, message):
from .models import Message
return Message.objects.create(
room=self.room_name,
user=self.scope['user'],
content=message
)
Routing
# chat/routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]
JavaScript Client
// Connect to WebSocket
const roomName = 'general';
const chatSocket = new WebSocket(
'ws://' + window.location.host + '/ws/chat/' + roomName + '/'
);
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
if (data.type === 'message') {
appendMessage(data.username, data.message);
} else if (data.type === 'join') {
appendNotification(data.username + ' joined the room');
}
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
// Send message
document.querySelector('#chat-form').onsubmit = function(e) {
e.preventDefault();
const messageInput = document.querySelector('#message-input');
chatSocket.send(JSON.stringify({
'message': messageInput.value
}));
messageInput.value = '';
};
Broadcasting from Views
# Send message from Django view
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
def send_notification(request):
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
'notifications',
{
'type': 'notification_message',
'message': 'New update available!',
}
)
return JsonResponse({'status': 'sent'})
Conclusion
Django Channels brings real-time capabilities to Django without sacrificing its simplicity. Build chat applications, notifications, and live updates while keeping your Django workflow.
Building real-time Django apps? Contact ZIRA Software for Channels development.