devto 2026-06-05 원문 보기 ↗
Real-time features have become table stakes for modern web applications. Whether it is a customer support widget, a collaborative tool, or a social platform, users expect instant communication without page refreshes. In this article, I will walk through how we built a production-ready real-time chat feature using Django Channels and React at UCDREAMS.
Django is traditionally synchronous. It handles one request at a time per worker. This works fine for standard HTTP requests, but WebSocket connections require persistent, bidirectional communication. Django Channels extends Django to handle WebSockets, background tasks, and asynchronous protocols alongside traditional HTTP.
The beauty of Channels is that it does not replace Django. It layers on top, letting you keep your existing models, ORM, authentication, and admin panel while adding real-time capabilities. For a team already invested in Django, this is a massive advantage over introducing an entirely separate real-time server.
Start by installing Django Channels and a channel layer. Redis is the recommended backend for production use:
channels==4.0.0
channels-redis==4.2.0
daphne==4.0.0
Configure your Django settings:
INSTALLED_APPS = [
...
"channels",
]
ASGI_APPLICATION = "your_project.asgi.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
},
},
}
The consumer handles WebSocket connections:
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}"
await self.channel_layer.group_add(self.room_group_name, self.channel_name)
await self.accept()
async def disconnect(self, close_code):
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"]
await self.channel_layer.group_send(
self.room_group_name,
{"type": "chat_message", "message": message, "user": self.scope["user"].username},
)
async def chat_message(self, event):
await self.send(text_data=json.dumps({
"message": event["message"],
"user": event["user"],
}))
On the React side, we use the native WebSocket API:
import React, { useState, useEffect, useRef } from "react";
const Chat = ({ roomName, username }) => {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
const ws = useRef(null);
useEffect(() => {
ws.current = new WebSocket(`ws://localhost:8000/ws/chat/${roomName}/`);
ws.current.onmessage = (event) => {
const data = JSON.parse(event.data);
setMessages((prev) => [...prev, data]);
};
return () => ws.current.close();
}, [roomName]);
const sendMessage = () => {
if (input.trim()) {
ws.current.send(JSON.stringify({ message: input }));
setInput("");
}
};
return (
<div className="chat-container">
<div className="messages">
{messages.map((msg, i) => (
<div key={i} className="message"><strong>{msg.user}:</strong> {msg.message}</div>
))}
</div>
<div className="input-area">
<input value={input} onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === "Enter" && sendMessage()} />
<button onClick={sendMessage}>Send</button>
</div>
</div>
);
};
In production, you will want authenticated WebSocket connections. Django Channels provides AuthMiddlewareStack which makes the user available in self.scope.user. For token-based auth with React, pass the token during connection.
For production deployment, consider these points:
At UCDREAMS (https://ucdreams.com), we have implemented this architecture for several client projects. One notable implementation powers a real-time customer support dashboard handling thousands of concurrent connections. The same pattern extends beyond chat to live notifications, collaborative editing, and real-time analytics.
You can also check out Captionator (https://captionator.ucdreams.com), a project where real-time WebSocket communication plays a key role in delivering captioning services with minimal latency.
Django Channels plus React gives you a powerful, scalable foundation for real-time features. The learning curve is gentle if you already know Django and React, and the architecture scales from a simple chat room to complex real-time applications. For custom web application development tailored to your business needs, reach out to UCDREAMS.