使用Django Channels实现WebSocket实时通信
Django Channels 是 Django 的一个扩展,允许 Django 处理非 HTTP 协议,如 WebSocket。本文将详细介绍如何使用 Django Channels 实现 WebSocket 实时通信,包括环境搭建、项目结构、安装 Channels、配置 ASGI、编写消费者、运行开发服务器、测试 WebSocket 连接等内容。
Django Channels 简介
环境搭建
安装 Django 和 Channels
pip install django channels
创建 Django 项目
django-admin startproject myproject
进入项目目录并创建一个新的应用。
cd myproject
django-admin startapp chat
配置 ASGI
myproject/settings.py
中添加 channels
到 INSTALLED_APPS
。 INSTALLED_APPS = [
# ...
'channels',
'chat',
]
在 myproject/asgi.py
中配置 ASGI。
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')
django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter({
'http': django_asgi_app,
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
编写消费者
chat/consumers.py
中定义 WebSocket 消费者。 import json
from channels.generic.websocket import AsyncWebsocketConsumer
累加器 = 0
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
)
# 接收来自 WebSocket 的消息
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
}
)
# 从房间组接收消息并发送给 WebSocket
async def chat_message(self, event):
message = event['message']
# 发送消息给 WebSocket
await self.send(text_data=json.dumps({
'message': message
}))
配置路由
chat/routing.py
中定义 WebSocket 路由。 from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]
创建模板
chat/templates/chat/room.html
中创建 WebSocket 客户端模板。 <!DOCTYPE html>
<html>
<head>
<title>Chat Room</title>
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Chat Room {{ room_name }}</h1>
<ul id="chat-log"></ul>
<input id="chat-message-input" type="text" size="100">
<button id="chat-message-submit">Send</button>
<script>
const roomName = '{{ room_name }}';
const socket = new WebSocket(`ws://${window.location.host}/ws/chat/${roomName}/`);
socket.onmessage = function(e) {
const data = JSON.parse(e.data);
const item = document.createElement('li');
item.textContent = data.message;
document.getElementById('chat-log').appendChild(item);
};
document.getElementById('chat-message-submit').onclick = function(e) {
const messageInputDom = document.getElementById('chat-message-input');
const message = messageInputDom.value;
socket.send(JSON.stringify({
'message': message
}));
messageInputDom.value = '';
};
</script>
</body>
</html>
创建视图
chat/views.py
中创建视图。 from django.shortcuts import render
def room(request, room_name):
return render(request, 'chat/room.html', {
'room_name': room_name
})
配置 URL
chat/urls.py
中配置 URL 路由。 from django.urls import path
from . import views
urlpatterns = [
path('<str:room_name>/', views.room, name='room'),
]
运行开发服务器
python manage.py runserver
测试 WebSocket 连接
http://127.0.0.1:8000/chat/room_name/
,其中 room_name
是你选择的房间名称。你应该能够看到聊天室页面,并且可以发送和接收消息。 总结
使用 Django Channels 可以轻松实现 WebSocket 实时通信功能。