vue+django实现一对一聊天功能的实例代码


Posted in Javascript onJuly 17, 2019

vue+django实现一对一聊天和消息推送的功能。主要是通过websocket,由于Django不支持websocket,所以我使用了django-channels。考虑到存储量的问题,我并没有把聊天信息存入数据库,服务端的作用相当于一个中转站。我只讲述实现功能的结构性代码,具体的实现还请大家看源代码。

前端聊天界面

前端消息提醒界面

后端代码

效果展示

vue+django实现一对一聊天功能的实例代码

实现过程

后端

首先,我们需要先定义websocket的两条连接路径。ws/chat/xxx/(xxx指代聊天组)这条路径是当聊天双方都进入同一个聊天组以后,开始聊天的路径。push/xxx/(xxx指代用户名)这条是指当有一方不在聊天组,另一方的消息将通过这条路径推送给对方。ws/chat/xxx/只有双方都进入聊天组以后才开启,而push/xxx/是自用户登录以后,直至退出都开启的。

websocket_urlpatterns = [
 url(r'^ws/chat/(?P<group_name>[^/]+)/$', consumers.ChatConsumer),
 url(r'^push/(?P<username>[0-9a-z]+)/$', consumers.PushConsumer),
]

我们采用user_a的id加上下划线_加上user_b的id的方式来命名聊天组名。其中id值从小到大放置,例如:195752_748418。当用户通过ws/chat/group_name/的方式向服务端请求连接时,后端会把这个聊天组的信息放入一个字典里。当连接关闭时,就把聊天组从字典里移除。

class ChatConsumer(AsyncJsonWebsocketConsumer):
 chats = dict()
 async def connect(self):
 self.group_name = self.scope['url_route']['kwargs']['group_name']
 await self.channel_layer.group_add(self.group_name, self.channel_name)
 # 将用户添加至聊天组信息chats中
 try:
  ChatConsumer.chats[self.group_name].add(self)
 except:
  ChatConsumer.chats[self.group_name] = set([self])
 #print(ChatConsumer.chats)
 # 创建连接时调用
 await self.accept()
 async def disconnect(self, close_code):
 # 连接关闭时调用
 # 将关闭的连接从群组中移除
 await self.channel_layer.group_discard(self.group_name, self.channel_name)
 # 将该客户端移除聊天组连接信息
 ChatConsumer.chats[self.group_name].remove(self)
 await self.close()

接着,我们需要判断连接这个聊天组的用户个数。当有两个用户连接这个聊天组时,我们就直接向这个聊天组发送信息。当只有一个用户连接这个聊天组时,我们就通过push/xxx/把信息发给接收方。

async def receive_json(self, message, **kwargs):
 # 收到信息时调用
 to_user = message.get('to_user')
 # 信息发送
 length = len(ChatConsumer.chats[self.group_name])
 if length == 2:
  await self.channel_layer.group_send(
  self.group_name,
  {
   "type": "chat.message",
   "message": message.get('message'),
  },
  )
 else:
  await self.channel_layer.group_send(
  to_user,
  {
   "type": "push.message",
   "event": {'message': message.get('message'), 'group': self.group_name}
  },
  )
 async def chat_message(self, event):
 # Handles the "chat.message" event when it's sent to us.
 await self.send_json({
  "message": event["message"],
 })
# 推送consumer
class PushConsumer(AsyncWebsocketConsumer):
 async def connect(self):
 self.group_name = self.scope['url_route']['kwargs']['username']
 await self.channel_layer.group_add(
  self.group_name,
  self.channel_name
 )
 await self.accept()
 async def disconnect(self, close_code):
 await self.channel_layer.group_discard(
  self.group_name,
  self.channel_name
 )
 # print(PushConsumer.chats)
 async def push_message(self, event):
 print(event)
 await self.send(text_data=json.dumps({
  "event": event['event']
 }))

前端

前端实现websocket就比较简单了。就是对websocket进行初始化,定义当websocket连接、关闭和接收消息时要执行哪些动作。

<script>
 export default {
 name : 'test',
 data() {
 return {
 websock: null,
 }
 },
 created() {
 this.initWebSocket();
 },
 destroyed() {
 this.websock.close() //离开路由之后断开websocket连接
 },
 methods: {
 initWebSocket(){ //初始化weosocket
 const wsuri = "ws://127.0.0.1:8080";
 this.websock = new WebSocket(wsuri);
 this.websock.onmessage = this.websocketonmessage;
 this.websock.onopen = this.websocketonopen;
 this.websock.onerror = this.websocketonerror;
 this.websock.onclose = this.websocketclose;
 },
 websocketonopen(){ //连接建立之后执行send方法发送数据
 let actions = {"test":"12345"};
 this.websocketsend(JSON.stringify(actions));
 },
 websocketonerror(){//连接建立失败重连
 this.initWebSocket();
 },
 websocketonmessage(e){ //数据接收
 const redata = JSON.parse(e.data);
 },
 websocketsend(Data){//数据发送
 this.websock.send(Data);
 },
 websocketclose(e){ //关闭
 console.log('断开连接',e);
 },
 },
 }
</script>

参考文章

Django Channels 实现点对点实时聊天和消息推送

Vue中使用websocket的正确使用方法

总结

以上所述是小编给大家介绍的vue+django实现一对一聊天功能的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
prototype 学习笔记整理
Jul 17 Javascript
了解jQuery技巧来提高你的代码
Jan 08 Javascript
关于IE BUG与字符串截取substr的解决办法
Apr 10 Javascript
Jquery增加鼠标中间功能mousewheel的实例代码
Sep 05 Javascript
为jQuery添加Webkit的触摸的方法分享
Feb 02 Javascript
jQuery多级弹出菜单插件ZoneMenu
Dec 18 Javascript
jQuery手动点击实现图片轮播特效
Apr 20 Javascript
以JavaScript来实现WordPress中的二级导航菜单的方法
Dec 14 Javascript
浅谈JavaScript 执行环境、作用域及垃圾回收
May 31 Javascript
jQuery实现图片轮播效果代码(基于jquery.pack.js插件)
Jun 02 Javascript
vue 自定义组件的写法与用法详解
Mar 04 Javascript
Javascript中Microtask和Macrotask鲜为人知的知识点
Apr 02 Javascript
微信小程序从注册账号到上架(图文详解)
Jul 17 #Javascript
js设置默认时间跨度过程详解
Jul 17 #Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
Jul 17 #Javascript
初试vue-cli使用HBuilderx打包app的坑
Jul 17 #Javascript
移动端吸顶fixbar的解决方案详解
Jul 17 #Javascript
基于webpack4+vue-cli3项目实现换肤功能
Jul 17 #Javascript
js getBoundingClientRect使用方法详解
Jul 17 #Javascript
You might like
php连接mysql数据库代码
2009/03/10 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
2013/01/29 PHP
php中动态修改ini配置
2014/10/14 PHP
thinkPHP5.0框架引入Traits功能实例分析
2017/03/18 PHP
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
JSON 和 JavaScript eval使用说明
2010/06/13 Javascript
DOM_window对象属性之--clipboardData对象操作代码
2011/02/03 Javascript
js document.write()使用介绍
2014/02/21 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
使用纯javascript实现经典扫雷游戏
2015/04/23 Javascript
JS+JSP通过img标签调用实现静态页面访问次数统计的方法
2015/12/14 Javascript
JavaScript_ECMA5数组新特性详解
2016/06/12 Javascript
js实现开启密码大写提示
2016/12/21 Javascript
Angular4.x通过路由守卫进行路由重定向实现根据条件跳转到相应的页面(推荐)
2018/05/10 Javascript
vue 中动态绑定class 和 style的方法代码详解
2018/06/01 Javascript
vue移动端微信授权登录插件封装的实例
2018/08/28 Javascript
对angularJs中2种自定义服务的实例讲解
2018/09/30 Javascript
tsconfig.json配置详解
2019/05/17 Javascript
JS实现容器模块左右拖动效果
2020/01/14 Javascript
[02:23]DOTA2英雄基础教程 幻影长矛手
2013/12/09 DOTA
[10:28]2018DOTA2国际邀请赛寻真——VGJ.S寻梦之路
2018/08/15 DOTA
R vs. Python 数据分析中谁与争锋?
2017/10/18 Python
Python使用zip合并相邻列表项的方法示例
2018/03/17 Python
解决PyCharm的Python.exe已经停止工作的问题
2018/11/29 Python
详解Ubuntu环境下部署Django+uwsgi+nginx总结
2020/04/02 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
2020/04/03 Python
Python之变量类型和if判断方式
2020/05/05 Python
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
Nicole Miller官方网站:纽约女装品牌
2019/09/14 全球购物
SK-II神仙水美国官网:SK-II美国
2020/02/25 全球购物
阿迪达斯中国官网:Adidas中国
2020/12/14 全球购物
小学教师培训感言
2014/02/11 职场文书
2015大学生实训报告
2014/11/05 职场文书
《迟到》教学反思
2016/02/24 职场文书
小学思想品德教学反思
2016/02/24 职场文书
python 实现两个变量值进行交换的n种操作
2021/06/02 Python