Welcome to our comprehensive guide on using WebSockets with Django Channels! This tutorial is designed for both beginners and intermediates, so let's dive right in.
WebSockets provide a two-way communication channel between a client (web browser) and a server. Unlike traditional HTTP requests, WebSockets allow real-time data transfer, making them perfect for applications that require instant updates, such as chat apps or live game updates.
Django Channels is a powerful framework extension that allows Django to handle WebSocket communication. It simplifies the process of building real-time applications with Django.
First, let's install Django Channels:
pip install daphne channelsNext, add 'channels' and 'channels_redis' to your INSTALLED_APPS in your Django project's settings file:
INSTALLED_APPS = [
# ...
'channels',
'channels_redis',
# ...
]And add the following to your asgi.py file:
import os
import django
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.core.asgi import get_asgi_application
from myapp.routing import chat_router
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter([
# Application will be added here
])
),
})A WebSocket consumer handles WebSocket communication. Let's create a simple chat application.
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_name = 'chat_%s' % self.scope['user'].username
self.room = await self.channel_layers.get_channel(self.room_name)
await self.room.group_add(self.room_name, self.channel_name)
await self.accept()
async def disconnect(self, close_code):
await self.room.group_discard(self.room_name, self.channel_name)
async def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
await self.room.send(text_data)
async def send(self, event):
message = event['message']
await self.send(text_data=json.dumps({
'message': message,
}))Finally, let's route our consumer in the chat_routing.py file:
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.urls import re_path
application = ProtocolTypeRouter({
"websocket": AuthMiddlewareStack(
URLRouter([
re_path(r'ws/chat/$', ChatConsumer.as_asgi()),
])
),
})Now, let's create a simple test client to test our WebSocket consumer:
from channels.testing import WebsocketCommunicator
def test_chat():
user = get_user_model().objects.create_user(username='test')
communicator = WebsocketCommunicator(
'/ws/chat/',
scope={'user': user},
read_timeout=None,
write_timeout=None,
)
communicator.connect()
communicator.wait_for_open()
communicator.send(json.dumps({'message': 'Hello, World!'}))
received = communicator.receive()
print(received)
communicator.close()That's it! You've just learned the basics of using WebSockets with Django Channels. With this knowledge, you can now build real-time applications with Django.
What is Django Channels used for?