mami/src/mami.js/websock.js

100 lines
3.2 KiB
JavaScript

#include eventtarget.js
const UmiWebSocket = function(url, useWorker) {
if(typeof useWorker !== 'boolean')
useWorker = (() => {
// Overrides
if(mami.settings.get('neverUseWorker'))
return false;
if(mami.settings.get('forceUseWorker'))
return true;
// Detect chromosomes
if((!!window.chrome || (!!window.Intl && !!Intl.v8BreakIterator)) && 'CSS' in window)
return true;
// Phones
if((/iphone|ipod|android|ie|blackberry|fennec/i).test(navigator.userAgent.toLowerCase()))
return true;
return false;
})();
const eventTarget = new MamiEventTarget('ws');
let send, close, sendInterval, clearIntervals;
if(useWorker) {
const worker = new Worker(MAMI_WS);
worker.addEventListener('message', ev => {
if(ev.data.act.startsWith('ws:'))
eventTarget.dispatch(ev.data.act.substring(3), ev.data.detail);
});
worker.postMessage({act: 'ws:open', url: url});
send = text => {
worker.postMessage({act: 'ws:send', text: text});
};
close = () => {
worker.postMessage({act: 'ws:close'});
};
sendInterval = (text, interval) => {
worker.postMessage({act: 'ws:send_interval', text: text, interval: interval});
};
clearIntervals = () => {
worker.postMessage({act: 'ws:clear_intervals'});
};
} else {
const websocket = new WebSocket(url), intervals = [];
websocket.addEventListener('open', ev => {
eventTarget.dispatch('open');
});
websocket.addEventListener('close', ev => {
eventTarget.dispatch('close', {
code: ev.code,
reason: ev.reason,
wasClean: ev.wasClean,
});
});
websocket.addEventListener('error', ev => {
eventTarget.dispatch('error');
});
websocket.addEventListener('message', ev => {
eventTarget.dispatch('message', {
data: ev.data,
origin: ev.origin,
lastEventId: ev.lastEventId,
});
});
send = text => {
websocket.send(text);
};
close = () => {
websocket.close();
};
sendInterval = (text, interval) => {
const intervalId = setInterval(() => {
if(websocket) {
websocket.send(text);
eventTarget.dispatch('call_interval', { id: intervalId });
}
}, interval);
intervals.push(intervalId);
eventTarget.dispatch('create_interval', { id: intervalId });
};
clearIntervals = () => {
for(let i = 0; i < intervals.length; ++i)
clearInterval(intervals[i]);
};
}
return {
isUsingWorker: useWorker,
send: send,
close: close,
sendInterval: sendInterval,
clearIntervals: clearIntervals,
watch: eventTarget.watch,
unwatch: eventTarget.unwatch,
};
};