之前有使用 websocket 判断登录状态的场景,每个页面都要一个 ws 连接,在支持 SharedWorker 的浏览器中可以将 websocket 放在 sharedWorker 中连接,这样同一个浏览器不同的标签页只需要建立一个 ws 连接即可;
// 页面中代码
let worker = null;
let portId = +new Date(); // sharedworker 不好确认port是否可用,此处通过定时轮询发心跳检测
init();
function init() {
// 第一个参数为worker对应的js文件,不同页面的该值必须完全一样才是同一个worker
worker = new SharedWorker('shared.js?t=2018081312')
worker.port.addEventListener('message', (e) => {
console.log(e.data)
})
worker.port.start()
worker.port.postMessage({
'type': 'msg',
'data': 'message from page'
})
console.log('curPort: ', portId)
heartbeat()
setInterval(() => {
heartbeat()
}, 3000)
}
// sharedworker 不好确认port是否可用,此处通过定时轮询发心跳检测
function heartbeat() {
worker.port.postMessage({
'type': 'heartbeat',
'data': portId
})
}
// shared.js
let ports = new Map()
onconnect = function (e) {
var port = e.ports[0];
port.onmessage = (e) => {
let type = e.data.type || '';
let data = e.data.data || '[invalid message format]';
switch (type) {
case 'heartbeat': // 心跳
ports.set(data, +new Date())
break;
case 'msg':
port.postMessage({
msg: 'message from page: ' + data,
ports: ports.size
})
break;
default:
break;
}
}
port.start();
// sharedworker 不好确认port是否可用,此处通过定时轮询判断
setInterval(() => {
let now = +new Date()
for (var [key, value] of ports) {
console.log(key + " = " + value);
if (now - value > 3100) {
// 3秒以上没发心跳,标签页已关闭
ports.delete(key)
}
}
}, 1000)
}
网友评论