多个页面 websocket 接收消息重复提醒问题

背景 :

网站登录成功后, 连接 websocket 接收消息, 网站可多标签页打开, 造成多个标签页都接受消息, 重复提醒

最开始是方案一状态了, 随后改成二, 发现问题后改成三, 最终方案为三

方案一:

  1. 每个页面登录成功后, 存储时间戳到页面程序时, 同时也存储到 localStorage (数组, JSON 形式)中, 退出登录, 出错, 重连, 页面关闭/刷新(beforeUnload) 时, 从 localStorage 中去掉该时间戳
  2. 页面接受到消息时, 判断当前页面时间戳是不是 localStorage 时间戳中的最大值, 是的话才提醒
  3. 弊端: localStorage 不会主动消失, 某些情况下时间戳最大的页面意外关闭后, localStorage 中仍存在值(遇到过, 但是没找到原因), 导致无提醒

方案二:

  1. 使用 cookie 替代 localStorage , 设置 cookie 自动过期, 随后使用 setInterval 为 cookie 定时延长有效期, 一旦页面关闭, cookie 过期自动消失
  2. 弊端 :
    1. setInterval 不一定准时执行, 可能导致某一时刻 cookie 中数据为空, 不提醒
    2. 页面在后台时, 一定时间后 chrome 会停止/延缓执行 setInterval , 导致数据为空, 不提醒
  3. 解决方案
    1. 网上搜索, 说可以用 web worker 让 setInterval 不休眠, 但是用了它我就不需要用 cookie 和 setInterval 了, 之前就是考虑到兼容性才不用它的
    2. 或者一些别的 hack (有人说播放一个空声音可以让 setInterval 不休眠)
    3. 最终决定用方案三

方案三:

  1. 参考 一种简单无副作用的同源跨页面数据同步方案 , 使用 sessionStorage 存储数据, 使用 localStorage 和 storage 监听来同步数据到 sessionStorage

后续:

方案三还是不行, sessionStorage 同步其他标签页的数据, 需要一定时间, 而 websocket 连接更快, 有个需求是 websocket 导致 websocket onopen 检测当前标签页数组时, 只能检查到当前标签页

于是改为延时 5s 再去检测标签页数组, 如果检测到数组当前标签页是标签页数组最小时间戳, 则发送 websocket 消息踢掉其他端; 但是, 如果用户点的块, 快速打开两个窗口, 这样会导致第二个窗口被踢掉, 等于还是有问题

相关推荐
爱怪笑的小杰杰23 分钟前
Cesium中的倒立四棱锥:从几何结构到交互式3D可视化
javascript·3d·arcgis·1024程序员节
小范同学_27 分钟前
Spring集成WebSocket
java·spring boot·websocket·spring·1024程序员节
不会算法的小灰1 小时前
JavaScript基础详解
开发语言·javascript·udp
十一吖i5 小时前
vue3表格显示隐藏列全屏拖动功能
前端·javascript·vue.js
徐同保7 小时前
tailwindcss暗色主题切换
开发语言·前端·javascript
生莫甲鲁浪戴7 小时前
Android Studio新手开发第二十七天
前端·javascript·android studio
细节控菜鸡9 小时前
【2025最新】ArcGIS for JS 实现随着时间变化而变化的热力图
开发语言·javascript·arcgis
拉不动的猪10 小时前
h5后台切换检测利用visibilitychange的缺点分析
前端·javascript·面试
桃子不吃李子10 小时前
nextTick的使用
前端·javascript·vue.js
Devil枫12 小时前
HarmonyOS鸿蒙应用:仓颉语言与JavaScript核心差异深度解析
开发语言·javascript·ecmascript