使用django+websocket+redis+channels实现简易聊天室

打印 上一主题 下一主题

主题 973|帖子 973|积分 2919

使用django+websocket+redis+channels实现简易聊天室

1.创建一个django项目

从存储项目的文件夹进入cmd命令行终端,输入以下命令创建chatroom项目
  1. django-admin startproject chatroom
复制代码
然后再进入项目文件夹,打开cmd命令行终端,输入以下命令创建chat应用
  1. python manage.py startapp chat
复制代码
2.安装所需模块

channels的功能必须依赖于redis数据库,除了安装channels之外,还需安装channels_redis模块,我们使用pip指令分别安装channels和channels_redis,指令如下:
  1. pip install channels
  2. pip install channels_redis
  3. #channels的功能依赖模块
  4. 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,配置如下:
  1. INSTALLED_APPS = [
  2.     'django.contrib.admin',
  3.     'django.contrib.auth',
  4.     'django.contrib.contenttypes',
  5.     'django.contrib.sessions',
  6.     'django.contrib.messages',
  7.     'django.contrib.staticfiles',
  8.     'channels',
  9.     'chat'
  10. ]
复制代码
(6)由于channels的功能依赖与redis数据库,因此还需在settings.py里设置channels的功能设置,配置信息如下:
  1. ASGI_APPLICATION = 'chatroom.routing.application'
  2. CHANNEL_LAYERS={
  3.     'default':{
  4.         'BACKEND':'channels_redis.core.RedisChannelLayer',
  5.         'CONFIG':{
  6.             "hosts":[('127.0.0.1',6379)],
  7.         },
  8.     },
  9. }
复制代码
(7)功能配置CHANNEL_LAYERS用于设置redis数据库的连接方式,ASGI_APPLICATION指向chatroom的routing.py定义的application对象,该对象把django与channels建立连接,打开chatrooom的routing.py添加如下内容:
  1. from channels.auth import AuthMiddlewareStack
  2. from channels.routing import ProtocolTypeRouter
  3. from channels.routing import URLRouter
  4. from .urls import websocket_urlpatterns
  5. application = ProtocolTypeRouter({
  6.     'websocket':AuthMiddlewareStack(
  7.         URLRouter(
  8.             websocket_urlpatterns
  9.         )
  10.     ),
  11. })
复制代码
(8)在chatroom的urls.py中定义路由对象urlpatterns和websocket_urlpatterns,代码如下:
  1. from django.urls import path,include
  2. from .consumers import ChatConsumer
  3. urlpatterns = [
  4.     path("",include(("chat.urls","chat"),namespace="chat"))
  5. ]
  6. websocket_urlpatterns=[
  7.     #使用同步方式实现
  8.     #path('ws/chat/<room_name>/',ChatConsumer),
  9.     #如果使用异步方式实现,路由的视图必须调用as_asgi()
  10.     path('ws/chat/<room_name>/',ChatConsumer.as_asgi()),
  11. ]
复制代码
(9)在chatroom的consumers.py中定义视图类ChatConsumer,代码如下:
  1. from channels.generic.websocket import AsyncWebsocketConsumer
  2. import json
  3. class ChatConsumer(AsyncWebsocketConsumer):
  4.     async def connect(self):
  5.         print("一个客户端连接了服务器")
  6.         self.room_name=self.scope['url_route']['kwargs']['room_name']
  7.         self.room_group_name='chat_%s' % self.room_name
  8.         #join room group
  9.         await self.channel_layer.group_add(
  10.             self.room_group_name,
  11.             self.channel_name
  12.         )
  13.         await  self.accept()
  14.     async def disconnect(self, code):
  15.         # leave room group
  16.         await self.channel_layer.group_discard(
  17.             self.room_group_name,
  18.             self.channel_name
  19.         )
  20.         print("一个客户端断开了连接")
  21.     # receive message from websocket
  22.     async def receive(self, text_data=None, bytes_data=None):
  23.         text_data_json=json.loads(text_data)
  24.         message=text_data_json["message"]
  25.         # send message to room group
  26.         await self.channel_layer.group_send(
  27.             self.room_group_name,
  28.             {
  29.                 'type':'chat_message',
  30.                 'message':message
  31.             }
  32.         )
  33.     # receive message from room group
  34.     async def chat_message(self,event):
  35.         message=event['message']
  36.         # send message to websocket
  37.         await self.send(text_data=json.dumps({
  38.             'message':message
  39.         }))
复制代码
4.web在线聊天功能

(1)在项目应用chat的urls.py中分别定义路由newChat和room,代码如下:
  1. from django.urls import path
  2. from .views import *
  3. urlpatterns = [
  4.     #用于开启新的聊天室
  5.     path('',newChat,name="newChat"),
  6.     #创建聊天室
  7.     path('<room_name>/',room,name="room")
  8. ]
复制代码
(2)在chat的views.py中定义视图,代码如下:
  1. from django.shortcuts import render
  2. #用于创建或进入聊天室
  3. def newChat(request):
  4.     return render(request,'chat.html',locals())
  5. #创建聊天室
  6. def room(request,room_name):
  7.     return render(request,'room.html',locals())
复制代码
(3)编写chat.html模板文件
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Title</title>
  6. </head>
  7. <body>
  8. 请输入聊天室名称
  9. <br/>
  10. <input id="input" type="text" size="30" />
  11. <br/>
  12. <input id="submit" type="button" value="进入">
  13. </body>
  14. </html>
复制代码
(4)编写room.html模板文件
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>聊天室{{ room_name }}</title>
  6. </head>
  7. <body>
  8. <textarea id="chat_log" cols="50" rows="6"></textarea>
  9. <br/>
  10. <input id="input" type="text" size="50"/><br/>
  11. <input id="submit" type="button" value="发送"/>
  12. </body>
  13. </html>
复制代码
5.测试聊天室功能

运行项目,打开谷歌浏览器并访问127.0.0.1:8000,在文本输入框输入聊天室名称,并单击进入,如下图所示:

当成功创建聊天室room0001后,打开另一个浏览器访问127.0.0.1:8000/room0001,聊天室已有两位用户在线,然后使用谷歌浏览器发送消息,发现在另一浏览器可以实时看到消息内容,如下图所示:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

勿忘初心做自己

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表