docker run --restart=always -p 6379:6379 --name redis -d redis:7.0.12 --requirepass zhangdapeng520
参考文档:https://channels.readthedocs.io/en/latest/installation.html
pip install "channels[daphne]"
新增:chat/templates/chat/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Rooms</title>
</head>
<body>
请输入您要进入的房间名称<br>
<input id="room-name-input" type="text" size="100"><br>
<input id="room-name-submit" type="button" value="进入房间">
<script>
// 输入框聚焦
document.querySelector('#room-name-input').focus();
// 输入框按下enter键,相当于点击提交按钮
document.querySelector('#room-name-input').onkeyup = function(e) {
if (e.key === 'Enter') {
document.querySelector('#room-name-submit').click();
}
};
// 提交按钮点击
document.querySelector('#room-name-submit').onclick = function(e) {
// 获取房间名称
const roomName = document.querySelector('#room-name-input').value;
// 重定向到指定房间
window.location.pathname = '/chat/' + roomName + '/';
};
</script>
</body>
</html>
修改:chat/views.py
from django.shortcuts import render
def index(request):
"""首页路由"""
return render(request, "chat/index.html")
新增:chat/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
修改:Django5Websocket/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("chat/", include("chat.urls")),
path("admin/", admin.site.urls),
]
启动服务,浏览器访问:http://localhost:8000
新增:chat/consumers.py
import json
from channels.generic.websocket import WebsocketConsumer
class ChatConsumer(WebsocketConsumer):
"""Websocket通信类"""
def connect(self):
"""建立连接"""
self.accept()
def disconnect(self, close_code):
"""断开连接"""
pass
def receive(self, text_data):
"""接收消息"""
# 转换为JSON类型
text_data_json = json.loads(text_data)
# 提取消息
message = text_data_json["message"]
# 重新发送JSON文本消息
self.send(text_data=json.dumps({"message": message}))
新增:chat/routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
# 定义websocket的连接
re_path(r"ws/chat/(?P<room_name>\w+)/$", consumers.ChatConsumer.as_asgi()),
]
修改:Django5Websocket/wsgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
from chat.routing import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Django5Websocket.settings')
django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websoket": AllowedHostsOriginValidator(
AuthMiddlewareStack(URLRouter(websocket_urlpatterns))
)
})
修改:chat/views.py
from django.shortcuts import render
def index(request):
"""首页路由"""
return render(request, "chat/index.html")
def room(request, room_name):
"""房间路由"""
return render(request, "chat/room.html", {"room_name": room_name})
新增:chat/templates/chat/room.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Room</title>
</head>
<body>
{#聊天日志#}
<textarea id="chat-log" cols="100" rows="20"></textarea><br>
{#消息输入框#}
<input id="chat-message-input" type="text" size="100"><br>
{#提交按钮#}
<input id="chat-message-submit" type="button" value="Send">
{#房间名称#}
{{ room_name|json_script:"room-name" }}
<script>
// 提取房间名称
const roomName = JSON.parse(document.getElementById('room-name').textContent);
// 创建websocket连接
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');
};
// 关闭websocket
chatSocket.onclose = function (e) {
console.error('聊天websocket连接已经被关闭');
};
// 消息输入框自动聚焦
document.querySelector('#chat-message-input').focus();
// 消息输入框的enter事件
document.querySelector('#chat-message-input').onkeyup = function (e) {
if (e.key === 'Enter') {
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>
迁移数据:
python manage.py migrate
安装Redis:
docker run --restart=always -p 6379:6379 --name redis -d redis:7.0.12 --requirepass zhangdapeng520
安装依赖:
pip install channels_redis
配置信息:
ASGI_APPLICATION = 'Django5Websocket.asgi.application'
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": ["redis://:zhangdapeng520@127.0.0.1:6379/0"],
},
},
}
启动服务,浏览器访问:http://localhost:8000/chat/test/