masterchd

微信小程序 -- 聊天室小程序(云开发)

从微信小程序开发社区更新watch接口之后,一直在构思这个项目。项目已经完成很久,但是一直都没有空写一篇博客记录展示一下。

开源地址

wx-cloud-im: 基于微信云开发 cloudbase 构建聊天小程序 提供即时通讯

技术栈

云开发 NodeJS

功能实现

  • 即时消息监听推送

使用watch接口(见附录),对数据库信息变动进行监听,实现 订阅-发布 形式的消息推送,同时在小程序端也完成了消息推送聊天界面变化的动画实现

  • 文本内容安全核验

使用微信小程序openapi对文本内容安全进行校验

  • 图片内容安全核验及重复性检查

将图片转为Buffer形式上传,并进行内容安全校验,同时计算BufferMD5值,实现重复性检查

  • 历史消息查询

通过对scroll-viewID锚点的计算,达到平滑切换信息的效果

  • 小黑屋功能:禁止用户发言

无法通过内容安全校验的信息会被记录下来,管理员可以调用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,只需要做如下几个步骤

  1. 自定义数据集合,为不同用户之间聊天分配不同的 roomId

  2. 引用组件时传入不同roomId即可

    <chat-box roomId="{{roomId}}"></chat-box>
    
  3. 调用消息发送云函数时,传入 roomId

TIPS

建议复用index/index.js页面,只需跳转该页面时,携带roomId参数,并赋值给data中的roomId即可

 onLoad: function (options){
	this.setData({
		roomId:options.roomId
	})
}

附录

watch

支持端:小程序 2.8.1, Web

监听集合中符合查询条件的数据的更新事件。使用 watch 时,支持 where, orderBy, limit,不支持 field

参数

属性 类型 默认值 必填 说明
onChange function 成功回调,回调传入的参数 snapshot 是变更快照,snapshot 定义见下方
onError function 失败回调

返回值

Watcher 对象

属性 类型 说明
close function 关闭监听,无需参数,返回 Promise,会在关闭完成时 resolve

参数说明

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 操作时有此信息

QueueType 枚举值

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

DataType 枚举值

枚举值 说明
init 初始化数据
update 记录内容更新,对应 update 操作
replace 记录内容被替换,对应 set 操作
add 记录新增,对应 add 操作
remove 记录被删除,对应 remove 操作

返回值说明

返回值 Watcher 上只有一个 close 方法,可以用于关闭监听。

orderBy 与 limit

2.9.2 起,在监听时支持使用 orderBylimit,如果不传或版本号低于 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()

分类:

技术点:

相关文章: