剛剛過去的六月,國內游戲迷們都剛剛體驗過一場盛大的游戲發布會 —— 2020 騰訊游戲年度發布會,由於疫情的原因,今年的發布會在線上舉行,不過,得益於雲開發和小程序的豐富體驗,本次發布會還是得到了游戲玩家們的認可。
實時數據同步的問題該如何解決?
在發布會過程中,一個重要的環節就是跟隨着活動的進展,每個環節都會有自己的定制互動。例如和平精英環節,會有和平精英專場掉落抽獎、和平精英閃現社區彈幕、議程也需要高亮和平精英模塊,如下圖:
這就要求小程序能夠讓所有在觀看直播的游戲玩家同時看到抽獎、寶盒等功能,實現實時交互。
此外,也會有一些場景需要做到議程高亮同一個模塊,抽獎和閃現社區彈幕卻是不同游戲的。在對所有的功能點進行分析后,我們發現,最多需要 90+ 開關來完成實時控制,因此,這也要求我們可以實時的對這些功能的展示進行控制。
實時數據同步的常見三種方案
在明確了訴求后,我們分析可能的實現方案:
- 接口輪詢:接口輪詢是常規操作,但在后台需要考慮好高並發的問題的。特別是大型游戲發布會,參與的游戲玩家人數會非常多,給后台帶來的壓力是巨大的。
- json文件輪詢 —— 在發布系統更新發布包含當前環節信息的json,小程序輪詢方式請求json文件。但這個方案頁面反應不夠及時,壓力從也后台轉移到了當天負責更新json文件的同學身上。
- 雲開發數據庫的實時數據推送 -— 小程序原生能力,開箱即用,無需管理長連,無需編寫服務端代碼,無需搭建和管理基礎設施,自動收到更新推送。
綜合評估,認為還是使用雲開發數據庫的實時數據推送更好,簡單易上手,也是小程序的原生能力。調研發現雲開發的 watch 給到每個用戶的最大限制連接數是5萬,而我們預估活動當天的 DAU 超過限制,因此,聯系了雲開發的同事進行擴容,將限制提高,並進行了壓測,確保不出問題。事實上在活動整個過程,甚至是峰值都毫無壓力,輕松扛過用戶請求。
使用雲開發數據庫的實時數據推送讓整個開發變得十分簡單,只需要一個 API —— watch 就足以完成所有的開發。小程序可以通過 watch 實時監聽數據庫變更,在收到包含更新內容的推送后,做出相應的實時響應。
如何實現
在具體的實現方面,也十分簡單,你可以參考我們的代碼進行。
我們將相關的監聽代碼進行了封裝,方便在不同情況下調用。如果你有一些特定場景下才執行操作的邏輯,可以直接在 watch 的 onChange 回調中調用進行。
// 監聽當前議程開關
loadAdminConfig(cb) {
let that = this
const db = wx.cloud.database()
that.globalData.adminWatch = db.collection('adminConfig').watch({
onChange: function (result) {
let adminData = result.docChanges[0].doc
console.log(adminData)
if(adminData.agenda_id > 108){
}
},
onError: function (err) {
console.error('the watch closed because of error', err)
}
})
}
並在合適的地方設置開始監聽,在頁面onshow的時候開始監聽,onhide的時候關閉監聽,這樣既不浪費監聽數,也能盡量避免計划外的操作導致watch斷連后無法重新連接。
// onShow 開始監聽
onShow: function(){
app.loadAdminConfig()
}
// onHide 關閉監聽
onHide: function () {
app.globalData.adminWatch && app.globalData.adminWatch.close().then(() => {
app.globalData.adminWatch = null
})
}
通過這樣的邏輯,我們實現了管理員在發布會環節開始才放開彈幕互動入口:
議程有抽獎,才會出現抽獎入口,並且展示的是提供當前抽獎環節獎品的產品logo:
主持人口播“查看Spark幸運鵝中獎結果吧!”的時候,會全屏彈窗展示中獎名單,充滿儀式感!
發布會或者線下項目必須要考慮周全,都是一次性短時間高並發活動,沒有機會給你查漏補缺。所以我們還給watch想了個備案,監聽失敗(onError)的時候就用上面提到的第2個方案開始每秒輪詢同步更新的json文件,json里的數據和結構跟watch的一樣,所以整體交互流程方面是不需要做額外修改的。結果也證明雲開發數據庫的watch是非常靠譜的,輪詢都沒用到。
總結
作為承載騰訊游戲年度發布會首次線上舉辦、首次TOC、首次進行實時互動的小程序,它也算是良好的完成了自己的任務。