如何用云开发打造“万人同屏”高并发实时互动小程序
刚刚过去的六月,国内游戏迷们都刚刚体验过一场盛大的游戏发布会 —— 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、首次进行实时互动的小程序,它也算是良好的完成了自己的任务。
特别要感谢腾讯云和小程序提供的好用、易用、靠谱的实时数据推送能力 watch,让我们的创意能更好的落地
- linux命令和awk
- django集成celery之callback方式link_error和on_failure
- 使用beanstalkd实现定制化持续集成过程中pipeline
- 用SQLite查看编辑android导出的微信聊天记录
- 使用HDFS客户端java api读取hadoop集群上的信息
- 使用Fabric一键批量部署上线/线上环境监控
- springboot使用zookeeper(curator)实现注册发现与负载均衡
- django使用xlwt导出excel文件
- redis的sentinel主从切换(failover)与Jedis线程池自动重连
- Hadoop通过HCatalog编写Mapreduce任务访问hive库中schema数据
- 伪排练:NLP灾难性遗忘的解决方案
- java优雅的使用elasticsearch api
- springboot mybatis优雅的添加多数据源
- java通过shield链接Elasticsearch
- 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 数组属性和方法
- 【MySQL】通过SQL_Thread快速恢复binlog
- 渗透系列之flask框架开启debug模式漏洞分析
- Android之ImageSwitcher的实例详解
- Android中HTTP请求中文乱码解决办法
- Android编程之播放器MediaPlayer实现均衡器效果示例
- Android studio点击跳转WebView详解
- Android webveiw 出现栈错误解决办法
- Android开发之实现手势滑动的功能
- Android编程实现带有单选按钮和复选按钮的dialog功能示例
- Android中Retrofit 2.0直接使用JSON进行数据交互
- Android自定义Drawable实现圆形和圆角
- Android jni调试打印char阵列的实例详解
- 写JavaScript函数不得不知的高级技巧
- Android编程视频播放API之MediaPlayer用法示例
- Android实现点击缩略图放大效果