微信小程式--聊天室小程式(雲開發)

Kindear發表於2021-09-03

微信小程式 -- 聊天室小程式(雲開發)

從微信小程式開發社群更新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()

相關文章