这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
需求背景
只第一个连入的视频可播放,后面连入的只可播放截图;当第一个视频断开连接,则下一个连入的可播放视频,其它的还是播放截图。
简而言之,争夺视频播放权限;谁先抢到是谁的。
视频流是使用websocket进行连接的,所以断开视频是需要断开websocket连接。
bug场景
自带浏览器Safari(第一个视频)断网后,会先跳转“默认跳转的url”,重连网络后从默认跳转的页面-手动点击浏览器返回到上一个视频页面,播放截图,而非视频,但是视频开关是开启的。
问题分析
- 页面跳转后,第一个视频未断开连接,导致回退后变成第二个连接者,只能播放截图。
- Safari回退,无刷新,导致视频开关显示错误。
问题解决
一、Tab页切换、断网等场景下,断开视频链接(Tab页关闭时不需要处理,浏览器会自己释放所有资源)。
1.使用visibilitychange事件,监听页面可见性变化。
visibilitychange
visibilitychange事件,可以跟踪页面以下可见性的变化:
- Tab页的切换(Tab页之间的切换,在PC上,指浏览器每个标签页的切换;在Mobile上,指打开一个新的页面)
- Tab页或浏览器窗口关闭。
可用以下代码进行测试:
document.addEventListener("visibilitychange", function(){
document.title = document.hidden ? "用户离开了" : "用户回来了";
});
document.visibilityState
document.visibilityState属性发生变化,就会触发visibilitychange事件,
document.visibilityState属性有三个属性值:
hidden:页面彻底不可见(所有浏览器都支持)。visible:页面至少一部分可见(所有浏览器都支持)。prerender:页面即将或正在渲染,处于不可见状态(支持预渲染的浏览器支持)。
所以,如果我们只是想判断页面的可见性,可以通过监听visibilitychange事件,判断document.visibilityState属性值是否是hidden,即可得到预期结果。
代码实现
window.addEventListener('visibilitychange', visibilitychange);
function visibilitychange() {
if ('visible' === document.visibilityState) {
location.reload();
}else{
closeVideoWS()
}
}
2.断网时断开视频连接
断网时server端是无感知的,client端会触发onerror、onclose事件,所以需要在onopen事件里,增加心跳来帮助server端断掉连接。
二、监听回退事件,重新reload页面。
因为不止Safari浏览器有回退不reload的问题,所以我们在回退事件里统一加上reload事件。
pageshow
window.addEventListener('pageshow', fixBrowserBack)
function fixBrowserBack(event){
//event.persisted判断是否后退进入
if(event.persisted){
location.reload();
}
}
至此,问题大致解决,我们明天见。