import { Message } from 'element-ui' import { listen, unlisten, publish, subscribe, unsubscribe } from '@/utils/mqtt' const cache = new Map() let listening = false export function watch ({ productId, id }, cb, expired) { if (!listening) { listen(onMessage) listening = true } let inst = cache.get(id) if (!inst || !inst.cb) { subscribe(`${productId}/${id}/screenshot/reply`) console.log('screenshot subscribe', id, '-> success') } if (inst) { inst.cb = cb } else { cache.set(id, inst = createInst(productId, id, cb)) } if (retry(inst, expired)) { screenshot(id, true) } else { cb(inst) } } export function check (deviceId, expired) { const inst = cache.get(deviceId) if (retry(inst, expired)) { screenshot(deviceId, true) } } function retry (inst, expired = 30000) { if (!inst) { return false } if (inst.waiting && inst.timestamp + 10000 >= Date.now()) { return false } if (inst.base64 && inst.timestamp + expired >= Date.now()) { return false } return true } export function unwatch (deviceId) { const inst = cache.get(deviceId) if (inst) { inst.cb = null const { productId, deviceId } = inst unsubscribe(`${productId}/${deviceId}/screenshot/reply`) console.log('screenshot unsubscribe', deviceId, '-> success') } } export function screenshot (deviceId, silence) { const inst = cache.get(deviceId) if (inst && !inst.waiting) { inst.waiting = true inst.timestamp = Date.now() inst.base64 = null publish(`${inst.productId}/${inst.deviceId}/screenshot/ask`, JSON.stringify({ timestamp: `${inst.timestamp}` })).then( () => { startTimer(inst) }, () => { inst.waiting = false if (!silence) { Message({ type: 'warning', message: '正在连接,请稍后重试' }) } } ).finally(() => { emit(inst) }) } } function createInst (productId, deviceId, cb) { return { productId, deviceId, cb, timer: -1, waiting: false, timestamp: Date.now(), base64: null } } function startTimer (inst) { clearTimeout(inst.timer) inst.timer = setTimeout(() => { inst.waiting = false emit(inst) }, 20000) } function emit (inst) { inst.cb && inst.cb(inst) } function onMessage (topic, message) { const result = /^(\d+)\/(\d+)\/screenshot\/reply$/.exec(topic) if (result) { const inst = cache.get(result[2]) if (inst) { clearTimeout(inst.timer) inst.waiting = false inst.timestamp = Date.now() inst.base64 = `data:image/jpeg;base64,${message.replace(/\s/g, '')}` emit(inst) } } } export function clear () { if (listening) { cache.forEach(({ deviceId }) => { unwatch(deviceId) }) unlisten(onMessage) listening = false } cache.clear() }