时间:2021-05-26
vue+django实现一对一聊天和消息推送的功能。主要是通过websocket,由于Django不支持websocket,所以我使用了django-channels。考虑到存储量的问题,我并没有把聊天信息存入数据库,服务端的作用相当于一个中转站。我只讲述实现功能的结构性代码,具体的实现还请大家看源代码。
前端聊天界面
前端消息提醒界面
后端代码
效果展示
实现过程
后端
首先,我们需要先定义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"], })# 推送consumerclass 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实现一对一聊天功能的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Django的ORM有多种关系:一对一,多对一,多对多各自定义的方式为:一对一:OneToOneField多对一:ForeignKey多对多:ManyToMan
按思路来聊:类似微信,点击用户可以进入一对一聊天页面;另有聊天框列表包含所有存在聊天记录的一对一聊天框,点击进入聊天页面。【数据结构】因为双方都有聊天记录,所以
django外键使用一对一因为django中处于安全和方便将数据库中的表封装成模型,所以很多sql原生的功能无法使用,比如leftjoin,但是我们可以使用外键
本文实例讲述了Laravel5.1框架模型一对一关系实现与使用方法。分享给大家供大家参考,具体如下:这篇文章主要记录模型的一对一关系,关联关系是Model的一种
一、延迟加载 resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、colle