Vue与Django结合实现一对一实时聊天及消息推送

作者:青团子

时间:2026-10-23

浏览:311

本文介绍基于Vue前端与Django后端,利用django-channels库实现一对一实时聊天功能。通过定义ws/chat和push两条WebSocket路径,分别处理在线组内消息转发与离线用户消息推送。后端不存储聊天记录,仅作为中转站,前端负责界面渲染与连接管理,完整展示了前后端交互的核心逻辑。

文章目录

Vue与Django实现一对一实时聊天及消息推送概述

本文展示如何利用Vue前端与Django后端实现一对一聊天及消息推送功能。核心方案基于WebSocket协议,鉴于原生Django对WebSocket支持有限,项目引入了django-channels库进行扩展。出于存储成本考虑,服务端不将聊天内容持久化至数据库,而是充当消息中转角色。此处仅呈现实现功能的关键结构代码,完整逻辑请参阅源代码。

前端聊天界面

前端消息提醒界面

后端代码

效果展示

Vue与Django实现一对一实时聊天及消息推送概述

实现过程详解

实现过程

后端

首先,需定义两条WebSocket连接路径。路径格式为ws/chat/xxx/(其中xxx代表聊天组标识),该路径仅在双方用户同时进入同一聊天组时激活,用于实时聊天。另一条路径为push/xxx/(xxx代表用户名),用于消息推送,当一方未处于聊天组时,另一方发送的消息将通过此路径送达。ws/chat/xxx/仅在双方均加入聊天组后开启,而push/xxx/自用户登录起至退出前始终保持开启状态。

后端WebSocket路由配置


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值较小的用户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实现一对一聊天功能的实例代码,希望能对读者有所帮助。如有任何疑问,欢迎留言,小编会及时回复。感谢大家对本站的支持!若本文对您有帮助,欢迎转载,请注明出处,谢谢!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章