# 实时数据推送

2.8.1

# 介绍

云开发数据库支持实时推送变更数据的能力,给定查询条件,每当数据库更新而导致查询条件对应的查询结果发生变更时,小程序可收到一个更新事件,其中可获取更新内容和更新后的查询结果快照。

实时数据推送有广泛应用场景,此处是一些示例:

  1. 聊天/即时通信:小游戏内聊天、大厅广播、区服广播等;企业内部小程序中的即时通信能力等
  2. 多人小游戏:使用状态同步的小游戏,如棋牌类等回合制游戏
  3. 协作工具:如在线协作文档、团队任务管理等
  4. 实时应用状态同步:以信息流为例,可以实时获取最新文章、以及最新评论、点赞、通知等内容,让交互更顺畅自然

工具中新建云开发快速启动模板,可以查看到使用实时数据推送能力搭建的即时通信 demo

# 监听

调用 Collection 上的 watch 方法即可监听给定查询条件对应的数据,支持搭配使用 orderBylimit(从 2.9.2 起监听支持 orderBylimit)。

示例:

const db = wx.cloud.database()
const watcher = db.collection('todos')
  // 按 progress 降序
  .orderBy('progress', 'desc')
  // 取按 orderBy 排序之后的前 10 个
  .limit(10)
  .where({
    team: 'our dev team'
  })
  .watch({
    onChange: function(snapshot) {
      console.log('docs\'s changed events', snapshot.docChanges)
      console.log('query result snapshot after the event', snapshot.docs)
      console.log('is init data', snapshot.type === 'init')
    },
    onError: function(err) {
      console.error('the watch closed because of error', err)
    }
  })
// ...
// 等到需要关闭监听的时候调用 close() 方法
// watcher.close()

onChangeonError 是必传参数。onChange 用于接收变更快照,onError 用于处理监听错误。如果监听发起失败或监听过程中出现不可恢复的错误,则会终止监听并通过 onError 抛出异常。onChange 会在第一次监听初始化及后续数据变更时收到推送事件。第一次初始化时会收到的查询条件对应的查询结果(此处不会有默认 20 条上限,包含集合中所有满足查询条件的记录),后续变更事件会包含变更内容和变更后的查询结果快照。

onChange 收到的 snapshot 变更快照中带有如下字段:

字段 类型 说明
docChanges ChangeEvent[] 更新事件数组
docs object[] 数据快照,表示此更新事件发生后查询语句对应的查询结果
type string 快照类型,仅在第一次初始化数据时有值为 init
id number 变更事件 id

ChangeEvent 记录变更事件的内容包括:

字段 类型 说明
id number 更新事件 id
queueType string 列表更新类型,表示更新事件对监听列表的影响,枚举值,定义见 QueueType
dataType string 数据更新类型,表示记录的具体更新类型,枚举值,定义见 DataType
docId string 更新的记录 id
doc object 更新的完整记录
updatedFields object 所有更新的字段及字段更新后的值,key 为更新的字段路径,value 为字段更新后的值,仅在 update 操作时有此信息
removedFields string[] 所有被删除的字段,仅在 update 操作时有此信息

DataType 枚举值

枚举值 说明
init 初始化数据
update 记录内容更新,对应 update 操作
replace 记录内容被替换,对应 set 操作
add 记录新增,对应 add 操作
remove 记录被删除,对应 remove 操作
limit 记录因 limit 排序而被进入/离开列表

QueueType 枚举值

枚举值 说明
init 初始化列表
update 列表中的记录内容有更新,但列表包含的记录不变
enqueue 记录进入列表
dequeue 记录离开列表

变更事件会细分记录数据变更类型 dataType 和监听列表变更类型 queueType,其可能的搭配和意义如下。

dataType queueType 说明
init init 监听开始时的初始化数据
update update 记录部分更新,更新后仍在查询结果列表中
update enqueue 记录部分更新,更新后进入查询结果列表
update dequeue 记录部分更新,更新后离开查询结果列表
replace update 记录被替换,更新后仍在查询结果列表中
replace enqueue 记录被替换,更新后进入查询结果列表
replace dequeue 记录被替换,更新后离开查询结果列表
add enqueue 记录是新增记录,新增后进入查询结果列表
remove dequeue 记录被删除,离开查询结果列表

监听 API 文档

# orderBy 与 limit

2.9.2

2.9.2 起,在监听时支持使用 orderBylimit,如果不传或版本号低于 2.9.2,则默认按 id 降序排列(等同于 orderBy('id', 'desc')),limit 默认不存在即取所有数据。使用 limit 时,若记录因排序问题而非记录变更时进入或离开队列,此时变更事件的 dataTypelimit

在监听中,orderBy 最多可以指定 5 个排序字段,limit 最大值为 200。

# 注意事项与系统限制

监听返回的数据不受默认 20 条限制

监听返回的数据可能超过 20 条,不受小程序端默认 20 条上限限制。

监听支持 where, orderBy, limit 语句

监听支持 where, orderBylimit 语句,暂不支持 field 语句。

监听记录数限制

一次监听的记录数上限为 5000,若超出上限会抛错并停止监听。监听过大量的数据时初始化会较慢,对监听效率也有影响,如果预期监听发起时少于 5000,但后续有可能超过 5000,请注意在即将超过时重新监听并保证不超过 5000。

注意集合权限设置

集合的读权限设置在实时数据推送里同样生效,如果权限是设置为仅可读用户自己的数据,则监听的时候无法监听到非用户自己创建的数据。

# 最佳实践

只监听必要的数据

监听时应明确查询条件,只监听必须用到的数据,避免监听不必要的数据,以此提高初次加载数据的性能以及接收数据变更的性能。