使用django+websocket+redis+channels实现简易聊天室
1.创建一个django项目
从存储项目的文件夹进入cmd命令行终端,输入以下命令创建chatroom项目
django-admin startproject chatroom
然后再进入项目文件夹,打开cmd命令行终端,输入以下命令创建chat应用
python manage.py startapp chat
2.安装所需模块
channels的功能必须依赖于redis数据库,除了安装channels之外,还需安装channels_redis模块,我们使用pip指令分别安装channels和channels_redis,指令如下:
pip install channels
pip install channels_redis
#channels的功能依赖模块
pip install pypiwin32
3.在django中配置channels
(1)在项目应用chat里新建urls.py文件
(2)在chatroom文件夹里创建文件consumers.py和routing.py,文件名可以自行命名
(3)在项目应用chat里新建templates文件夹,在templates文件夹里创建模板文件chat.html和room.html,项目结构如下:
(4)执行整个项目的数据迁移,因为channels需要使用django内置的会话session机制,用于区分和识别每个用户的身份信息
(5)在django的settings.py里将第三方功能应用channels和chat添加到chatroom,配置如下:
INSTALLED_APPS = [
\'django.contrib.admin\',
\'django.contrib.auth\',
\'django.contrib.contenttypes\',
\'django.contrib.sessions\',
\'django.contrib.messages\',
\'django.contrib.staticfiles\',
\'channels\',
\'chat\'
]
(6)由于channels的功能依赖与redis数据库,因此还需在settings.py里设置channels的功能设置,配置信息如下:
ASGI_APPLICATION = \'chatroom.routing.application\'
CHANNEL_LAYERS={
\'default\':{
\'BACKEND\':\'channels_redis.core.RedisChannelLayer\',
\'CONFIG\':{
\"hosts\":[(\'127.0.0.1\',6379)],
},
},
}
(7)功能配置CHANNEL_LAYERS用于设置redis数据库的连接方式,ASGI_APPLICATION指向chatroom的routing.py定义的application对象,该对象把django与channels建立连接,打开chatrooom的routing.py添加如下内容:
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter
from channels.routing import URLRouter
from .urls import websocket_urlpatterns
application = ProtocolTypeRouter({
\'websocket\':AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
),
})
(8)在chatroom的urls.py中定义路由对象urlpatterns和websocket_urlpatterns,代码如下:
from django.urls import path,include
from .consumers import ChatConsumer
urlpatterns = [
path(\"\",include((\"chat.urls\",\"chat\"),namespace=\"chat\"))
]
websocket_urlpatterns=[
#使用同步方式实现
#path(\'ws/chat/<room_name>/\',ChatConsumer),
#如果使用异步方式实现,路由的视图必须调用as_asgi()
path(\'ws/chat/<room_name>/\',ChatConsumer.as_asgi()),
]
(9)在chatroom的consumers.py中定义视图类ChatConsumer,代码如下:
from channels.generic.websocket import AsyncWebsocketConsumer
import json
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
print(\"一个客户端连接了服务器\")
self.room_name=self.scope[\'url_route\'][\'kwargs\'][\'room_name\']
self.room_group_name=\'chat_%s\' % 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, code):
# leave room group
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
print(\"一个客户端断开了连接\")
# receive message from websocket
async def receive(self, text_data=None, bytes_data=None):
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
}))
4.web在线聊天功能
(1)在项目应用chat的urls.py中分别定义路由newChat和room,代码如下:
from django.urls import path
from .views import *
urlpatterns = [
#用于开启新的聊天室
path(\'\',newChat,name=\"newChat\"),
#创建聊天室
path(\'<room_name>/\',room,name=\"room\")
]
(2)在chat的views.py中定义视图,代码如下:
from django.shortcuts import render
#用于创建或进入聊天室
def newChat(request):
return render(request,\'chat.html\',locals())
#创建聊天室
def room(request,room_name):
return render(request,\'room.html\',locals())
(3)编写chat.html模板文件
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>Title</title>
</head>
<body>
<div>请输入聊天室名称</div>
<br/>
<input id=\"input\" type=\"text\" size=\"30\" />
<br/>
<input id=\"submit\" type=\"button\" value=\"进入\">
<script>
document.querySelector(\'#input\').focus();
document.querySelector(\'#input\').onkeyup=function (e){
if (e.keyCode===13){
document.querySelector(\'#submit\').click();
}
};
document.querySelector(\'#submit\').onclick=function (e){
var roomName=document.querySelector(\'#input\').value;
window.location.pathname=\'/\'+roomName + \'/\';
}
</script>
</body>
</html>
(4)编写room.html模板文件
<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<title>聊天室{{ room_name }}</title>
</head>
<body>
<textarea id=\"chat_log\" cols=\"50\" rows=\"6\"></textarea>
<br/>
<input id=\"input\" type=\"text\" size=\"50\"/><br/>
<input id=\"submit\" type=\"button\" value=\"发送\"/>
<script>
var roomName=\'{{ room_name }}\';
var chatSocket=new WebSocket(
\'ws://\' + window.location.host+\'/ws/chat/\' + roomName +\'/\'
);
{#将chat发送的数据显示在多行文本输入框中#}
chatSocket.onmessage=function (e){
var data=JSON.parse(e.data);
var message=data[\'message\'];
document.querySelector(\'#chat_log\').value+=(message +\'\\n\');
};
{#关闭网页与chat的Channels连接#}
chatSocket.onclose=function (e){
console.error(\'Chat socket closed unexpectedly\');
};
document.querySelector(\'#input\').focus();
document.querySelector(\'#input\').onkeyup=function (e){
if (e.keyCode===13){
document.querySelector(\'#submit\').click();
}
};
{#网页向chat的channels发送数据#}
document.querySelector(\'#submit\').onclick=function (e){
var messageInputDom = document.querySelector(\'#input\');
var message=messageInputDom.value;
chatSocket.send(JSON.stringify({
\'message\':message
}));
messageInputDom.value=\'\';
}
</script>
</body>
</html>
5.测试聊天室功能
运行项目,打开谷歌浏览器并访问127.0.0.1:8000,在文本输入框输入聊天室名称,并单击进入,如下图所示:
当成功创建聊天室room0001后,打开另一个浏览器访问127.0.0.1:8000/room0001,聊天室已有两位用户在线,然后使用谷歌浏览器发送消息,发现在另一浏览器可以实时看到消息内容,如下图所示:
来源:https://www.cnblogs.com/minqiliang/p/16548465.html
本站部分图文来源于网络,如有侵权请联系删除。