SharedWorker demo

2018-08-13  本文已影响0人  forever_youyou

之前有使用 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)
}
上一篇 下一篇

猜你喜欢

热点阅读