云开发如何为腾讯游戏年度发布会保驾护航?
受疫情影响,2020 腾讯游戏年度发布会以线上的形式进行。区别于往年的线下 toB模式,线上面对的群体比较广泛,同时也希望借此机会能更贴近玩家,所以在线上发布的内容和线上呈现形式等方面,都要考虑如何做得更加玩家向。
发布会从预热到结束,历经42天,吸引了大量玩家的关注。因此,参与量如此大、互动如此多、内容如此丰富的线上服务类互动小程序如何抗住高并发得以稳定运行?
在经验方面,团队做过很多类似的线下服务类互动小程序,如TIEM年会小程序、英雄联盟观赛助手和CF赛事助手小程序等。
但这次却是第一次做参与量如此大、互动如此多、内容如此丰富的线上服务类互动小程序,其中有两个关键点:如何实现实时互动以及如何抗住高并发?
所以笔者在经过调研,并且找了几个有丰富线下服务经验的同学取经,跟开发、品牌、产品多次讨论后,最终确定选用云开发作为解决方案。
关于实现实时互动,我们团队已经很有经验了,做了不下3个线下实时互动的案例,关键点在于使用了云开发 watch [2]。但是这次发布会参与量大、官方阵地要稳定,所以肯定需要有更多解决方案来选择及互补。
这次小程序的最大亮点是50+个发布会环节,每个环节有自己的定制互动。例如和平精英环节,会有和平精英专场掉落抽奖、和平精英闪现社区弹幕、议程也需要高亮和平精英模块等,如下图所示:
也有的环节是议程高亮同一个模块,抽奖和闪现社区弹幕却是不同游戏的。盘点了下,需要用90+个开关来实时控制。
那么怎么实现90+个开关实时控制页面上所有的互动?我们考虑过下面三个方案:
方案一:接口轮询——常规操作,后台需要考虑好高并发的问题。
方案二:json 文件轮询——在发布系统更新发布包含当前环节信息的 json,小程序轮询方式请求 json 文件。这个方案页面反应不够及时,压力从后台转移到了当天负责更新 json 文件的同学身上。
方案三:云开发数据库的实时数据推送——原生能力[3],开箱即用,无需管理长连,无需编写服务端代码,无需搭建和管理基础设施,自动收到更新推送。
自然是第三个方案最好,简单易上手、小程序原生能力!但我们还需要确定一件事情:它所能支持的最大连接数。
watch 给到每个用户最大限制是 5w 连接数。我们预估了发布会当天 DAU,5w 连接数是不够用的,最后在云开发同事们的帮助下完成了扩容服务,并且提前做了压测,在活动访问峰值期间都毫无压力。
所以我们就选择了第三个方案——云开发数据库的实时数据推送。非常简单,记住一个API——watch 就够了。小程序可通过 watch 实时监听数据库变更,收到包含更新内容的推送后,做出实时响应。
毕竟有90+个开关,为了方便品牌大大操作,我们也做了一个简单的小程序管理端。
管理端开启某个议程开关,小程序监听的集合数据就更新到对应议程的所有配置,包括章节id、产品id、议程id、是否有抽奖、是否有闪现弹幕、是否需要预约等。
而发布会小程序,就是在监听议程和答题集合的数据是否有更新,来判断当前议程以及当前答题环节。
//监听当前议程开关
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)
},
onError: function (err) {
console.error('the watch closed because of error', err)
}
})
}
还需要在适合的地方设置开始监听,在页面 onshow 的时候开始监听,onhide 的时候关闭监听,这样既不浪费监听数,也能尽量避免计划外的操作导致 watch 断连后无法重新连接。
onShow: function(){
app.loadAdminConfig()
}
onHide: function () {
app.globalData.adminWatch && app.globalData.adminWatch.close().then(() => {
app.globalData.adminWatch = null
})
}
watch 使用起来就是那么简单,效果却是超乎想象!简单的模块是否显示用 wx:if 即可,有些需要在某个议程才去请求接口做逻辑处理的,可以写在 watch 里。
<view wx:if="{{adminData.lottery_status}}" bindtap="lottery">抽奖</view>
<view wx:if="{{queStatus[item]==='choose'}}">请答题</view>
<view wx:if="{{queStatus[item]==='waiting'}}">等待开奖</view>
<view wx:if="{{queStatus[item]==='luckylist'}}">中奖名单</view>
//监听当前议程开关
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
if(adminData.agenda_id > 108){
}
},
onError: function (err) {
console.error('the watch closed because of error', err)
}
})
}
发布会环节开始才放开弹幕互动入口。
议程有抽奖,才会出现抽奖入口,并且展示的是提供当前抽奖环节奖品的产品logo。
主持人口播:“查看 Spark 幸运鹅中奖结果吧!”的时候,会充满仪式感的全屏弹窗展示中奖名单,这也是通过管理端的议程开关控制的。
实时监听除了议程,还有答题环节。整个发布会有5个答题抽奖环节,每个题目在停止答题后,会进行后台抽奖。品牌和产品验证名单没问题后,即可展示中奖名单。
发布会或者线下项目必须要考虑周全,都是一次性短时间高并发活动,没有机会给你查漏补缺。
所以我们还给 watch 想了一个备案:监听失败(onError)的时候就用上面提到的第二个方案开始每秒轮询同步更新的 json 文件,json 里的数据和结构跟 watch 的一样,所以整体交互流程方面是不需要做额外修改的。
结果也证明云开发数据库的watch是非常靠谱的,轮询都没用上~
作为承载腾讯游戏年度发布会首次线上举办、首次 toC、首次进行实时互动的小程序,它也算是良好完成了自己的任务。特别要感谢云开发提供的好用、易用、靠谱的实时数据推送能力 watch,让我们的创意能更好的落地。
所有的经历都会成为财富,这次项目对每个人来说都是很多新知识领域的学习,感谢一起合作的伙伴们。
参考资料:
[1] 云开发watch:
https://developers.weixin.qq.com/minigame/dev/wxcloud/reference-sdk-api/database/collection/Collection.watch.html
[2] 云开发数据库实时数据推送能力:
https://developers.weixin.qq.com/community/develop/article/doc/000e860d128680d5211981d3556013
文章来源:云加社区
点击文末阅读原文进入云开发社区官网,了解云开发的更多信息。
欢迎在下方评论区留言或在微信开放社区 进入云开发专区与我们交流。
☁
更多精彩
点击下方图片即可了解
△ 2020小程序云开发挑战赛报名开启,海量大奖等你来拿!
△ 用云开发快速构建最美AI毕业照小程序
由于公众号推送规则更改,请多多分享、点赞和“在看”,以及时获取云开发Cloudbase的最新动态。
点击在看让更多人发现精彩
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [奇淫巧技]GitHub个人页的新玩法
- 一致性哈希的分析与实现
- 关系型数据库查询语言 SQL 和图数据库查询语言 nGQL 对比
- 目标检测之评价指标 - mAP
- sass的基础用法
- Golang Gin 实战(十四)| 文件托管、反向代理百度网站、自实现API网关
- ceph修复pg inconsistent
- 基于kubernetes的kong网关实战
- 移动端适配必须掌握的基本概念和适配方案
- [OHIF-Viewers]医疗数字阅片-医学影像-Redux中的reducer到底是什么,以及它为什么叫reducer?
- 【从零开始用Swift开发一个iOS应用(仿微博)】开篇-1. demo上手体验
- 数据结构与算法-二维数组中的查找
- 卷积神经网络之 - GoogLeNet / Inception-v1
- 卷积神经网络之 - Alexnet
- Linux系列之学会使用Top命令进行系统监控