小程序使用云开发实现聊天

背景

之前做的两个项目都涉及到即时通讯功能,近期帮朋友开发小程序时也有这个需求,因为没有后端,所以决定使用云开发来实现通讯功能。 即时通讯的关键点在于即时,在之前的开发中我们可以通过websocket长连接来实现,云开发中又怎样来实现呢?

场景分析

  1. A点击B的头像发起聊天时,根据双方id生成唯一的聊天室group_id,用于存储聊天数据。若group_id存在,则获取聊天数据
  2. 考虑到分别需要对聊天列表和聊天数据进行存储,所以我们需要建立两个集合,分别命名为msgList、msgData
  3. 发起聊天时,需要往msgList集合添加一条数据,若存在,则进行更新覆盖,用户更新聊天最后一句内容与聊天结束时间,用于展示聊天列表
  4. 进行聊天详情页,根据group_id获取对应聊天数据并进行数据渲染
  5. 聊天窗口内实时监听聊天数据,进行数据填充

具体实现

消息发起方

发起聊天时,生成group_id并往 msgList 集合中存储一条信息,用以记录A、B双方聊天关系。

COPY
1
2
// group_id使用两个用户uid之和,便于对数据进行查询
let group_id = Number(uid_a) + Number(uid_b)

生成的group_id,并使用 Collection.whereCollection.get 方法从 msgList 集合中获取聊天数据

COPY
1
2
3
4
5
6
7
8
9
10
let _db = db.collection('msgList')
// 获取聊天记录
_db
.where({groupId: groupId})
.get()
.then(res=>{
that.setData({
talkData: res.data
})
})

发送文本消息,将数据在本地添加到talkData中,并使用 Collection.add() 方法将数据添加到 msgData 集合中

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const chatData = {
toId: '', // 接收人id
toAvatar: '', // 接收人头像
toName: '', // 接收人昵称
fromId: '', // 发送人id
fromAvatar: '', // 发送人头像
fromName: '', // 发送人昵称
groupId: '', // 聊天室id
msgType: 'text', // 消息类型
lastContent: InputContent, // 消息内容
sendTime: new Date(), // 当前时间
...
}
// 记录聊天数据
db.collection('msgData')
.add({data: chatData})
.then(res=>{
console.log(res)
if(res.errMsg == "collection.add:ok"){
// 发送成功,数据放入msgData

}else{
// 发送失败的逻辑处理
}
})
消息接收方

消息接收时,关键在于使用 Collection.watch 方法 监听集合中符合查询条件的数据的更新事件 ,在这里,我们结合 Collection.where 方法一起使用

COPY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 监听数据变化
const that = this
let _db = db.collection('msgData')
_db
.where({toId: ''}) // 查询条件: 返回toId == 对方id的数据
.watch({
onChange: function(res) {
let reviceMsg = res.docChanges[0]
if(reviceMsg.dataType == 'add'){
let talkData = that.data.talkData
talkData.push(reviceMsg.doc) // 将实时监听到的数据添加到本地数据中
that.setData({
talkData: talkData
})
}
},
onError: function(err) {
console.error('the watch closed because of error', err)
}
})
作者: 果汁
文章链接: https://guozhigq.github.io/post/796d8a17.html
版权声明: All posts on this blog are licensed under the CC BY-NC-SA 4.0 license unless otherwise stated. Please cite 果汁来一杯 !