Photo by freepik
Building a real-time chat application using Django Channels and WebSockets is an excellent project to demonstrate how to handle asynchronous web protocols in Django. Here’s a step-by-step guide to help you build a basic real-time chat application.
Prerequisites
Before starting, make sure you have the following installed:
- Python (preferably 3.7+)
- Django (install using pip install django)
- Django Channels (install using pip install channels)
- Redis (for channel layers and WebSocket communication.
Also read: “Create a Program to Download Images from a Website Using Scrapy in Python”
Step-by-Step Guide
1. Set Up a Django Project
First, create and set up a Django project:
django-admin startproject chat_app
cd chat_app
python manage.py startapp chat
2. Install Django Channels
Install Django Channels by running:
pip install channels
Then, add channels to your INSTALLED_APPS in settings.py:
# chat_app/settings.py
INSTALLED_APPS = [
# Django apps...
'channels',
'chat', # Add your chat app here
]
# Specify ASGI application
ASGI_APPLICATION = 'chat_app.asgi.application'
3. Configure Channels and Redis for Channel Layers
Django Channels uses a channel layer to manage WebSockets. Redis is a popular choice for this.
Install Redis and Django’s Redis support:
pip install channels_redis
Now, add Redis configuration for Channels in settings.py:
# chat_app/settings.py
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)], # Adjust if your Redis server is elsewhere
},
},
}
4. Create an ASGI Configuration
Create the asgi.py file for ASGI server configuration. It will route WebSocket requests:
# chat_app/asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
import chat.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'chat_app.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
5. Create Routing for WebSockets
In your chat app, create a routing.py file to define WebSocket routes:
# 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()),
]
6. Build the Consumer to Handle WebSocket Connections
Consumers manage WebSocket connections. Create a consumers.py file in your chat app:
# 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()
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
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
}
)
# Receive message from room group
async def chat_message(self, event):
message = event['message']
# Send message to WebSocket
await self.send(text_data=json.dumps({
'message': message
}))
7. Define the Chat Room View
In your views.py file, create a view that renders the chat room:
# chat/views.py
from django.shortcuts import render
def room(request, room_name):
return render(request, 'chat/room.html', {
'room_name': room_name
})
8. Configure URL Routing for the Views
In chat/urls.py, set up URL routing for the chat room:
# chat/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('<str:room_name>/', views.room, name='room'),
]
Include the chat app’s URLs in the main urls.py file:
# chat_app/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('chat/', include('chat.urls')),
]
9. Create HTML and JavaScript for Chat
In the chat/templates/chat/room.html file, create the front end for the chat:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Chat Room</title>
</head>
<body>
<h1>Chat Room: {{ room_name }}</h1>
<textarea id="chat-log" cols="100" rows="20" readonly></textarea><br>
<input id="chat-message-input" type="text" size="100"><br>
<input id="chat-message-submit" type="button" value="Send">
<script>
const roomName = "{{ room_name }}";
const chatSocket = new WebSocket(
'ws://' + window.location.host + '/ws/chat/' + roomName + '/'
);
chatSocket.onmessage = function(e) {
const data = JSON.parse(e.data);
document.querySelector('#chat-log').value += (data.message + '\n');
};
chatSocket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
document.querySelector('#chat-message-input').focus();
document.querySelector('#chat-message-input').onkeyup = function(e) {
if (e.keyCode === 13) { // Enter key
document.querySelector('#chat-message-submit').click();
}
};
document.querySelector('#chat-message-submit').onclick = function(e) {
const messageInputDom = document.querySelector('#chat-message-input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message
}));
messageInputDom.value = '';
};
</script>
</body>
</html>
10. Run Redis and Django
Make sure Redis is running, then run the Django development server:
redis-server
python manage.py runserver
11. Testing the Chat Application
You can open multiple browser windows and navigate to different chat rooms by visiting URLs like:
http://127.0.0.1:8000/chat/room_name/
Replace room_name with any name you like to create or join that room. Messages sent from one browser window should appear in all others in the same room in real time.
Conclusion
You have now built a real-time chat application using Django Channels and WebSockets. This implementation supports basic real-time messaging, and you can extend it further with features like user authentication, chat histories, and private messaging.
Leave a Reply