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 相关文章推荐
JavaScript中变量提升 Hoisting
Jul 03 Javascript
javascript的字符串按引用复制和传递,按值来比较介绍与应用
Dec 28 Javascript
web开发人员学习jQuery的6大理由及jQuery的优势介绍
Jan 03 Javascript
深入浅析JavaScript中的constructor
Apr 19 Javascript
AngularJS 防止页面闪烁的方法
Mar 09 Javascript
Vue.js tab实现选项卡切换
May 16 Javascript
js下拉菜单生成器dropMenu使用方法详解
Aug 01 Javascript
基于node.js的fs核心模块读写文件操作(实例讲解)
Sep 10 Javascript
IntelliJ IDEA 安装vue开发插件的方法
Nov 21 Javascript
vue自定义tap指令及tap事件的实现
Sep 18 Javascript
vue.js的vue-cli脚手架中使用百度地图API的实例
Jan 21 Javascript
vue路由插件之vue-route
Jun 13 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制作图型计数器的例子
2006/10/09 PHP
fleaphp crud操作之find函数的使用方法
2011/04/23 PHP
PHP的preg_match匹配字符串长度问题解决方法
2014/05/03 PHP
PHP传参之传值与传址的区别
2015/04/24 PHP
PHP性能优化大全(php.ini)
2016/05/20 PHP
php使用PDO从数据库表中读取数据的实现方法(必看)
2017/06/02 PHP
thinkphp5 + ajax 使用formdata提交数据(包括文件上传) 后台返回json完整实例
2020/03/02 PHP
PHP tp5中使用原生sql查询代码实例
2020/10/28 PHP
Maps Javascript
2007/01/22 Javascript
jQuery创建平滑的页面滚动(顶部或底部)
2013/02/26 Javascript
javascript dom追加内容实现示例
2013/09/21 Javascript
JS命令模式例子之菜单程序
2016/10/10 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
js获取一组日期中最近连续的天数
2017/05/25 Javascript
AngularJs分页插件使用详解
2018/06/30 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
2018/08/11 Javascript
vue2.0 路由模式mode=&quot;history&quot;的作用
2018/10/18 Javascript
JS异步宏队列与微队列原理区别详解
2020/07/02 Javascript
vue深度监听(监听对象和数组的改变)与立即执行监听实例
2020/09/04 Javascript
JavaScript Html实现移动端红包雨功能页面
2021/01/10 Javascript
[02:09]DOTA2辉夜杯 EHOME夺冠举杯现场
2015/12/28 DOTA
Python和php通信乱码问题解决方法
2014/04/15 Python
python进阶教程之词典、字典、dict
2014/08/29 Python
Python操作MongoDB数据库PyMongo库使用方法
2015/04/27 Python
python删除列表中重复记录的方法
2015/04/28 Python
Python2与python3中 for 循环语句基础与实例分析
2017/11/20 Python
python实现二级登陆菜单及安装过程
2019/06/21 Python
python用WxPython库实现无边框窗体和透明窗体实现方法详解
2020/02/21 Python
pycharm远程连接vagrant虚拟机中mariadb数据库
2020/06/05 Python
浅谈TensorFlow之稀疏张量表示
2020/06/30 Python
美国眼镜网站:EyeBuyDirect
2017/04/13 全球购物
享受加州生活方式的时尚舒适:XCVI
2018/07/09 全球购物
CNC数控操作工岗位职责
2013/11/19 职场文书
公交公司毕业生求职信
2014/02/15 职场文书
公司联欢会策划方案
2014/05/19 职场文书
浅谈如何保证Mysql主从一致
2022/03/13 MySQL