互动直播中的前端技术——即时通讯( 三 )


  • 重连(超时<X次)
  • 换连接地址重连 (超时>=X次)
  • 重新获取连接地址(X<MAX)
  • 上层处理(超过MAX)
在重连X次后选择换地址 , 在一个地址失败后 , 选择重新去拿地址再去循环尝试 。具体的尝试次数根据实际业务来定 。当然在一次又一次失败中做好异常上报 , 以便于分析解决问题 。
接受消息优化在高并发的场景下尤其是聊天室场景 , 我们要做一定的消息合并与缓冲 , 来避免过多的UI绘制与应用阻塞 。
因此要约定好解析协议 , 服务端与客户端都做消息合并 , 并设置消息缓冲 。示例如下:
Fn.startMsgFlushTimer = function () {this.msgFlushTimer = setTimeout(() => {const msgs = this.msgBuffer.splice(0, BUFFERSIZE);// 回调消息通知this.onmsgs(msgs);if (!this.msgBuffer.length) {this.msgFlushTimer = null;} else {this.startMsgFlushTimer();}}, MSGBUFFERINTERVAL);};流量优化持久化存储在单聊场景中每次都同步全量的会话 , 历史消息等这是一个很大的代价 。此外关闭web也是一种比较容易的操作(基本上就需要重新同步一次) 。如果我们用增量的方式去同步就可以减少很多流量 。实现增量同步自然想到了web存储 。
常用web存储cookie , localStorage , sessionStorage不太能满足我们持久化的场景 , 然而html5的indexedDB正常好满足我们的需求 。IndexedDB 内部采用对象仓库(object store)存放数据 。所有类型的数据都可以直接存入 , 包括JavaScript对象 。indexedDB的api直接用可能会比较难受 , 可以使用 Dexie.js  ,  db.js 这些二次封装的库来实现业务的数据层 。
在满足持久化存储后, 我们便可以用时间戳 , 来进行增量同步 , 在收到消息通知时 , 存储到web数据库 。上层操作获取数据 , 优先从数据库获取数据 , 避免总是高频率、高数据量的与服务器通讯 。当然敏感性信息不要存在数据库或者增加点破解难度 , 毕竟所有web本地存储都是能看到的 。此外注意下存储大小还是有限制的 ,  每种浏览器可能不一样  , 但是远大于其他Web本地存储了 , 只要该放云端的数据放云端(比如云消息) , 不会有太大问题 。
在编码实现上 , 由于处理消息通知都是异步操作 , 要维护一个队列保证 入库时序  。此外要做好 降级方案  。
减少连接数在Web桌面端的互动直播场景 , 同一种页面开启了多个tab访问应该是很常见的 。业务上也会有多端互踢操作 , 但是对Web场景如果只能一个页面能进行互动那肯定是不行的 , 一不小心就不知道切到哪个tab上去了 。所以通常会设置一个多端在线的最大数 , 超过了就踢 。因而一个浏览器建立7 , 8个长链接是一件很寻常的事情 , 对于服务端资源也是一种极大的浪费 。
Web Worker可以为Web内容在后台线程中运行脚本提供了一种简单的方法 , 线程可以执行任务而不干扰用户界面 。并且可以将消息发送到创建它的JavaScript代码, 通过将消息发布到该代码指定的事件处理程序(反之亦然) 。虽然Web Worker中不能使用DOM API , 但是XHR , WebSocket这些通讯API并没有限制(而且可以操作本地存储) 。因此我们可以通过SharedWorker API创建一个执行指定脚本来共享web worker来实现多个tab之前的通讯复用 , 来达到减少连接数的目的 。在兼容性要求不那么高的场景可以尝试一下 。
小结本文介绍了互动直播中的即时通讯技术的在前端中应用 , 并分享了自己在工作开发中的一些经验 , 希望对您有所帮助 , 欢迎探讨 。
本文作者:吴杰




推荐阅读