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 相关文章推荐
FireFox中textNode分片的问题
Apr 10 Javascript
弹出广告特效代码(一个IP只弹出一次)
May 11 Javascript
JS 自动安装exe程序
Nov 30 Javascript
Js 获取HTML DOM节点元素的方法小结
Apr 24 Javascript
javascript克隆对象深度介绍
Nov 20 Javascript
JQuery表格内容过滤的实现方法
Jul 05 Javascript
动态加载jQuery的方法
Jun 16 Javascript
JS实现网站菜单拖拽移位效果的方法
Sep 24 Javascript
Axios学习笔记之使用方法教程
Jul 21 Javascript
javascript如何实现create方法
Nov 04 Javascript
vue 全局封装loading加载教程(全局监听)
Nov 05 Javascript
Ajax实现异步加载数据
Nov 17 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 array_merge下进行数组合并的代码
2008/07/22 PHP
php下目前为目最全的CURL中文说明
2010/08/01 PHP
php实例分享之mysql数据备份
2014/05/19 PHP
推荐十款免费 WordPress 插件
2015/03/24 PHP
php实现分页显示
2015/11/03 PHP
Highslide.js是一款基于js实现的网页中图片展示插件
2020/03/30 Javascript
jQuery学习笔记之jQuery的事件
2010/12/22 Javascript
图片onload事件触发问题解决方法
2011/07/31 Javascript
你必须知道的Javascript知识点之&quot;this指针&quot;的应用
2013/04/23 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
2013/12/10 Javascript
将字符串中由空格隔开的每个单词首字母大写
2014/04/06 Javascript
自己使用jquery写的一个无缝滚动的插件
2014/04/30 Javascript
jQuery实现仿淘宝带有指示条的图片转动切换效果完整实例
2015/03/04 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
Javascript中Array用法实例分析
2015/06/13 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
JS原生带小白点轮播图实例讲解
2017/07/22 Javascript
jquery+css3实现熊猫tv导航代码分享
2018/02/12 jQuery
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
layui前端框架之table表数据的刷新方法
2018/08/17 Javascript
解决vue 单文件组件中样式加载问题
2019/04/24 Javascript
vue 移动端注入骨架屏的配置方法
2019/06/25 Javascript
微信小程序顶部导航栏可滑动并选中放大
2019/12/05 Javascript
js生成1到100的随机数最简单的实现方法
2020/02/07 Javascript
vue接口请求加密实例
2020/08/11 Javascript
js 将多个对象合并成一个对象 assign方法的实现
2020/09/24 Javascript
python统计文本文件内单词数量的方法
2015/05/30 Python
Python实现爬取逐浪小说的方法
2015/07/07 Python
Django框架orM与自定义SQL语句混合事务控制操作
2019/06/27 Python
Django发送邮件功能实例详解
2019/09/02 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
总经理职责范文
2013/11/08 职场文书
法律专业应届生自荐信范文
2014/01/06 职场文书
加拿大留学自荐信
2014/01/28 职场文书
党风廉政承诺书
2014/03/27 职场文书
浅析Redis Sentinel 与 Redis Cluster
2021/06/24 Redis