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 相关文章推荐
jQuery 使用手册(五)
Sep 23 Javascript
js自定义鼠标右键的实现原理及源码
Jun 23 Javascript
微信企业号开发之微信考勤百度地图定位
Sep 11 Javascript
详解AngularJS如何实现跨域请求
Aug 22 Javascript
jQuery easyui刷新当前tabs的方法
Sep 23 Javascript
有关suggest快速删除后仍然出现下拉列表的bug问题
Dec 02 Javascript
axios进阶实践之利用最优雅的方式写ajax请求
Dec 20 Javascript
详解Angular2学习笔记之Html属性绑定
Jan 03 Javascript
原生js实现下拉选项卡
Nov 27 Javascript
为react组件库添加typescript类型提示的方法
Jun 15 Javascript
JavaScript TAB栏切换效果的示例
Nov 05 Javascript
浅谈react useEffect闭包的坑
Jun 08 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
从零开始 教你如何搭建Discuz!4.1论坛
2006/07/07 PHP
php中定时计划任务的实现原理
2013/01/08 PHP
php阻止页面后退的方法分享
2014/02/17 PHP
详解PHP处理字符串类似indexof的方法函数
2017/06/11 PHP
javascript 自定义事件初探
2009/08/21 Javascript
jQuery实现长文字部分显示代码
2013/05/13 Javascript
JavaScript学习笔记之取数组中最大值和最小值
2016/03/23 Javascript
Bootstrap Paginator分页插件与ajax相结合实现动态无刷新分页效果
2016/05/27 Javascript
针对BootStrap中tabs控件的美化和完善(推荐)
2016/07/06 Javascript
对javascript继承的理解
2016/10/11 Javascript
JavaScript 中对象的深拷贝
2016/12/04 Javascript
vue解决使用webpack打包后keep-alive不生效的方法
2018/09/01 Javascript
解决angularJS中input标签的ng-change事件无效问题
2018/09/13 Javascript
Vue 中的受控与非受控组件的实现
2018/12/17 Javascript
Node.js中package.json中库的版本号(~和^)
2019/04/02 Javascript
nodejs开发一个最简单的web服务器实例讲解
2020/01/02 NodeJs
2019年度web前端面试题总结(主要为Vue面试题)
2020/01/12 Javascript
vue 实现setInterval 创建和销毁实例
2020/07/21 Javascript
[09:13]DOTA2-DPC中国联赛 正赛 Ehome vs Magma 选手采访 1月19日
2021/03/11 DOTA
django 常用orm操作详解
2017/09/13 Python
Python除法之传统除法、Floor除法及真除法实例详解
2019/05/23 Python
python基于exchange函数发送邮件过程详解
2020/11/06 Python
css3实现3D文本悬停改变效果的示例代码
2019/01/16 HTML / CSS
欧洲最大的化妆品连锁公司:Douglas道格拉斯
2017/05/06 全球购物
自荐书模板
2013/12/15 职场文书
党员群众路线个人整改措施思想汇报
2014/10/12 职场文书
六年级学生期末评语
2014/12/26 职场文书
社区六一儿童节活动总结
2015/02/11 职场文书
2015年社区党务工作总结
2015/04/21 职场文书
小学生反邪教心得体会
2016/01/15 职场文书
2016年大学生党员承诺书
2016/03/24 职场文书
JS实现简单控制视频播放倍速的实例代码
2021/04/18 Javascript
Jupyter notebook 输出部分显示不全的解决方案
2021/04/24 Python
Java中CyclicBarrier和CountDownLatch的用法与区别
2021/08/23 Java/Android
Java 在线考试云平台的实现
2021/11/23 Java/Android
全新239军机修复记
2022/04/05 无线电