
从微信小程序开发社区更新watch接口之后,一直在构思这个项目。项目已经完成很久,但是一直都没有空写一篇博客记录展示一下。
wx-cloud-im: 基于微信云开发 cloudbase 构建聊天小程序 提供即时通讯
| 云开发 | NodeJS | 
使用
watch接口(见附录),对数据库信息变动进行监听,实现 订阅-发布 形式的消息推送,同时在小程序端也完成了消息推送聊天界面变化的动画实现
使用微信小程序
openapi对文本内容安全进行校验
将图片转为
Buffer形式上传,并进行内容安全校验,同时计算Buffer的MD5值,实现重复性检查
通过对
scroll-view的ID锚点的计算,达到平滑切换信息的效果
无法通过内容安全校验的信息会被记录下来,管理员可以调用
cloud-user-black云函数对对应用户进行封禁,同时计时器自动每天触发一次,用户到达封禁日期期限自动解除发言限制
scroll-view新消息和历史消息平滑的动画效果

chat-users 聊天室用户信息表
| 字段 | 说明 | 类型 | 
|---|---|---|
| _id | 数据库记录唯一ID | string | 
| openid | 用户唯一身份识别ID | string | 
| userInfo | 用户头像 昵称 地址等信息 | object | 
chat-users-ban 聊天室小黑屋信息表
| 字段 | 说明 | 类型 | 
|---|---|---|
| _id | 数据库记录唯一ID | string | 
| ban_date | 禁言时长 单位天 | number | 
| _createTime | 记录创建时间 | string | 
| _updateTime | 记录更新时间 | string | 
chat-msgs 消息记录表
| 字段 | 说明 | 类型 | 
|---|---|---|
| _id | 数据库记录唯一ID | string | 
| roomId | 会话房间号 | number | 
| openid | 消息发送者openid | string | 
| msgType | 消息类型 目前有 text image | string | 
| content | 消息内容 text :对应消息内容 image:对应图片地址 | string | 
| userInfo | 用户头像 昵称 地址等信息 | object | 
| _createTime | 消息创建时间 | string | 
chat-msgs-ban 非法消息记录表(内容/图片安全校验不通过)
| 字段 | 说明 | 类型 | 
|---|---|---|
| _id | 数据库记录唯一ID | string | 
| roomId | 会话房间号 | number | 
| openid | 消息发送者openid | string | 
| msgType | 消息类型 目前有 text image | string | 
| content | 消息内容 text :对应消息内容 image:对应图片地址 | string | 
| userInfo | 用户头像 昵称 地址等信息 | object | 
| _createTime | 消息创建时间 | string | 
项目提供的聊天室Demo为单聊天室模式,默认roomId = 1。为如果想要做成多用户聊天不同的形式,如QQ,只需要做如下几个步骤
TIPS
建议复用index/index.js页面,只需跳转该页面时,携带roomId参数,并赋值给data中的roomId即可
 onLoad: function (options){
	this.setData({
		roomId:options.roomId
	})
}监听集合中符合查询条件的数据的更新事件。使用 watch 时,支持 where, orderBy, limit,不支持 field。
| 属性 | 类型 | 默认值 | 必填 | 说明 | 
|---|---|---|---|---|
| onChange | function | 是 | 成功回调,回调传入的参数 snapshot 是变更快照,snapshot 定义见下方 | |
| onError | function | 是 | 失败回调 | 
Watcher 对象
| 属性 | 类型 | 说明 | 
|---|---|---|
| close | function | 关闭监听,无需参数,返回 Promise,会在关闭完成时 resolve | 
| 字段 | 类型 | 说明 | 
|---|---|---|
| docChanges | ChangeEvent[] | 更新事件数组 | 
| docs | object[] | 数据快照,表示此更新事件发生后查询语句对应的查询结果 | 
| type | string | 快照类型,仅在第一次初始化数据时有值为 init | 
| id | number | 变更事件 id | 
| 字段 | 类型 | 说明 | 
|---|---|---|
| id | number | 更新事件 id | 
| queueType | string | 列表更新类型,表示更新事件对监听列表的影响,枚举值,定义见 QueueType | 
| dataType | string | 数据更新类型,表示记录的具体更新类型,枚举值,定义见 DataType | 
| docId | string | 更新的记录 id | 
| doc | object | 更新的完整记录 | 
| updatedFields | object | 所有更新的字段及字段更新后的值,key 为更新的字段路径,value 为字段更新后的值,仅在 update 操作时有此信息 | 
| removedFields | string[] | 所有被删除的字段,仅在 update 操作时有此信息 | 
| 枚举值 | 说明 | 
|---|---|
| init | 初始化列表 | 
| update | 列表中的记录内容有更新,但列表包含的记录不变 | 
| enqueue | 记录进入列表 | 
| dequeue | 记录离开列表 | 
| 枚举值 | 说明 | 
|---|---|
| init | 初始化数据 | 
| update | 记录内容更新,对应 update 操作 | 
| replace | 记录内容被替换,对应 set 操作 | 
| add | 记录新增,对应 add 操作 | 
| remove | 记录被删除,对应 remove 操作 | 
返回值 Watcher 上只有一个 close 方法,可以用于关闭监听。
从 2.9.2 起,在监听时支持使用 orderBy 和 limit,如果不传或版本号低于 2.9.2,则默认按 id 降序排列(等同于 orderBy('id', 'desc')),limit 默认不存在即取所有数据。
示例代码:根据查询条件监听*
const db = wx.cloud.database()
const watcher = db.collection('todos')
  // 按 progress 降序
  .orderBy('progress', 'desc')
  // 取按 orderBy 排序之后的前 10 个
  .limit(10)
  // 筛选语句
  .where({
    // 填入当前用户 openid,或如果使用了安全规则,则 {openid} 即代表当前用户 openid
    _openid: '{openid}'
  })
  // 发起监听
  .watch({
    onChange: function(snapshot) {
      console.log('snapshot', snapshot)
    },
    onError: function(err) {
      console.error('the watch closed because of error', err)
    }
  })const db = wx.cloud.database()
const watcher = db.collection('todos').doc('x').watch({
  onChange: function(snapshot) {
    console.log('snapshot', snapshot)
  },
  onError: function(err) {
    console.error('the watch closed because of error', err)
  }
})const db = wx.cloud.database()
const watcher = db.collection('todos').where({
  _openid: 'xxx' // 填入当前用户 openid
}).watch({
  onChange: function(snapshot) {
    console.log('snapshot', snapshot)
  },
  onError: function(err) {
    console.error('the watch closed because of error', err)
  }
})
// ...
// 关闭
await watcher.close()