Building a Real-Time Chat Application with Django and WebSockets

A simple Django web application demonstrating Instant Messaging using WebSockets, Django Channels, Daphne and Redis
February 12, 2025 by
Building a Real-Time Chat Application with Django and WebSockets
Hamed Mohammadi
| No comments yet

In this post, I'll share my experience building a real-time chat application using Django and WebSocket technology. This project demonstrates how to implement instant messaging features in a Django application using Django Channels.

GitHub Repository

Project Overview

The Django Instant Messaging (IM) application is a demonstration of real-time communication features implemented using modern web technologies. It supports both public and private messaging, with features like online status tracking and message persistence.

Key Features

  • Real-time messaging using WebSocket
  • Public and private messaging capabilities
  • Live online user status tracking
  • Message history persistence
  • Automatic reconnection handling
  • User authentication
  • Responsive design

Technology Stack

  • Backend: Django 5.1 with Channels for WebSocket support
  • Server: Daphne (ASGI server)
  • Message Broker: Redis for real-time message handling
  • Frontend: Vanilla JavaScript with WebSocket API
  • Database: SQLite for data persistence

Technical Implementation

WebSocket Integration

The core of the real-time functionality is implemented using Django Channels, which extends Django's capabilities to handle WebSocket connections. Here's a simplified version of the WebSocket consumer:

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.user = self.scope["user"]
        self.room_name = "chat_room"
        await self.channel_layer.group_add(self.room_name, self.channel_name)
        await self.accept()

    async def receive(self, text_data):
        data = json.loads(text_data)
        message = data.get("message", "")
        recipient = data.get("recipient", None)

        # Handle private vs public messages
        if recipient:
            await self.send_private_message(message, recipient)
        else:
            await self.broadcast_message(message)

Message Persistence

Messages are stored in the database using a custom Message model:

class Message(models.Model):
    sender = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    content = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)
    is_private = models.BooleanField(default=False)
    recipient = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        related_name="received_messages",
        null=True,
        blank=True
    )

Real-Time Status Updates

The application maintains real-time user status through WebSocket connections. When users connect or disconnect, their status is broadcast to all connected users:

chatSocket.onopen = function(e) {
    console.log('WebSocket connection established');
    displaySystemMessage('Connected to chat server');
}

chatSocket.onclose = function(e) {
    if (reconnectAttempts < maxReconnectAttempts) {
        displaySystemMessage('Connection lost. Reconnecting...');
        setTimeout(connectWebSocket, reconnectDelay);
    }
}

Challenges and Solutions

Challenge 1: Message Delivery Reliability

One of the main challenges was ensuring reliable message delivery. The solution involves:

  • Implementing automatic reconnection
  • Message persistence in the database
  • Loading message history on connection

Challenge 2: User Status Synchronization

Maintaining accurate online user status required:

  • Real-time status broadcasting
  • Proper handling of disconnections
  • Status verification on new connections

Challenge 3: Private Messaging

Implementing private messaging while maintaining the WebSocket connection structure required:

  • Custom routing for private messages
  • User-specific channels
  • Proper message filtering

Lessons Learned

  1. Asynchronous Programming: Django Channels' async nature requires careful handling of database operations.
  2. WebSocket Management: Proper connection handling and reconnection strategies are crucial for reliability.
  3. State Management: Maintaining consistent state across multiple connections requires careful planning.

Future Improvements

While the current implementation serves as a good demonstration, several enhancements could be made:

  1. Message Encryption: Implementing end-to-end encryption for private messages
  2. File Sharing: Adding support for file transfers
  3. Read Receipts: Implementing message read status
  4. Message Threading: Adding support for threaded conversations
  5. User Typing Indicators: Showing when users are typing

Conclusion

Building this real-time chat application with Django demonstrated the framework's versatility in handling both traditional HTTP requests and WebSocket connections. Django Channels provides a robust foundation for real-time features, while maintaining Django's elegant development patterns.

The source code is available on GitHub under the GPL-3.0 license. Feel free to explore, use, or contribute to the project!

This project was created for demonstration purposes and serves as a learning resource for implementing real-time features in Django applications.

Building a Real-Time Chat Application with Django and WebSockets
Hamed Mohammadi February 12, 2025
Share this post
Tags
Archive

Please visit our blog at:

https://zehabsd.com/blog

A platform for Flash Stories:

https://readflashy.com

A platform for Persian Literature Lovers:

https://sarayesokhan.com

Sign in to leave a comment