162 lines
4.9 KiB
JavaScript
162 lines
4.9 KiB
JavaScript
'use strict';
|
|
|
|
// "fake" window object will contain "MsgWorker" after import
|
|
let window = {}; // jshint ignore:line
|
|
|
|
// import "MsgWorker" class
|
|
self.importScripts( self.name ); // jshint ignore:line
|
|
|
|
let MsgWorker = window.MsgWorker;
|
|
let socket = null;
|
|
let ports = [];
|
|
let characterPorts = [];
|
|
|
|
// init "WebSocket" connection ========================================================================================
|
|
let initSocket = (uri) => {
|
|
let MsgWorkerOpen = new MsgWorker('ws:open');
|
|
|
|
if(socket === null){
|
|
socket = new WebSocket(uri);
|
|
|
|
// "WebSocket" open -----------------------------------------------------------------------
|
|
socket.onopen = (e) => {
|
|
MsgWorkerOpen.meta({
|
|
readyState: socket.readyState
|
|
});
|
|
|
|
sendToCurrentPort(MsgWorkerOpen);
|
|
};
|
|
|
|
// "WebSocket message ---------------------------------------------------------------------
|
|
socket.onmessage = (e) => {
|
|
let response = JSON.parse(e.data);
|
|
|
|
let MsgWorkerSend = new MsgWorker('ws:send');
|
|
MsgWorkerSend.task( response.task );
|
|
MsgWorkerSend.meta({
|
|
readyState: this.readyState,
|
|
characterIds: response.characterIds
|
|
});
|
|
MsgWorkerSend.data( response.load );
|
|
|
|
broadcastPorts(MsgWorkerSend);
|
|
};
|
|
|
|
// "WebSocket" close ----------------------------------------------------------------------
|
|
socket.onclose = (closeEvent) => {
|
|
let MsgWorkerClosed = new MsgWorker('ws:closed');
|
|
MsgWorkerClosed.meta({
|
|
readyState: socket.readyState,
|
|
code: closeEvent.code,
|
|
reason: closeEvent.reason,
|
|
wasClean: closeEvent.wasClean
|
|
});
|
|
|
|
broadcastPorts(MsgWorkerClosed);
|
|
socket = null; // reset WebSocket
|
|
};
|
|
|
|
// "WebSocket" error ----------------------------------------------------------------------
|
|
socket.onerror = (e) => {
|
|
let MsgWorkerError = new MsgWorker('ws:error');
|
|
MsgWorkerError.meta({
|
|
readyState: socket.readyState
|
|
});
|
|
|
|
sendToCurrentPort(MsgWorkerError);
|
|
};
|
|
}else{
|
|
// socket still open
|
|
MsgWorkerOpen.meta({
|
|
readyState: socket.readyState
|
|
});
|
|
sendToCurrentPort(MsgWorkerOpen);
|
|
}
|
|
};
|
|
|
|
// send message to port(s) ============================================================================================
|
|
let sendToCurrentPort = (load) => {
|
|
ports[ports.length - 1].postMessage(load);
|
|
};
|
|
|
|
let broadcastPorts = (load) => {
|
|
// default: sent to all ports
|
|
let sentToPorts = ports;
|
|
|
|
// check if send() is limited to some ports
|
|
let meta = load.meta();
|
|
if(
|
|
meta &&
|
|
meta.characterIds &&
|
|
meta.characterIds !== 'undefined' &&
|
|
meta.characterIds instanceof Array
|
|
){
|
|
// ... get ports for characterIds
|
|
sentToPorts = getPortsByCharacterIds(meta.characterIds);
|
|
}
|
|
|
|
for(let i = 0; i < sentToPorts.length; i++){
|
|
sentToPorts[i].postMessage(load);
|
|
}
|
|
};
|
|
|
|
// port functions =====================================================================================================
|
|
let addPort = (port, characterId) => {
|
|
characterId = parseInt(characterId);
|
|
|
|
if(characterId > 0){
|
|
characterPorts.push({
|
|
characterId: characterId,
|
|
port: port
|
|
});
|
|
}else{
|
|
ports.push(port);
|
|
}
|
|
};
|
|
|
|
let getPortsByCharacterIds = (characterIds) => {
|
|
let ports = [];
|
|
|
|
for(let i = 0; i < characterPorts.length; i++){
|
|
for(let j = 0; j < characterIds.length; j++){
|
|
if(characterPorts[i].characterId === characterIds[j]){
|
|
ports.push(characterPorts[i].port);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ports;
|
|
};
|
|
|
|
// "SharedWorker" connection ==========================================================================================
|
|
self.addEventListener('connect', (event) => { // jshint ignore:line
|
|
let port = event.ports[0];
|
|
addPort(port);
|
|
|
|
port.addEventListener('message', (e) => {
|
|
let MsgWorkerMessage = e.data;
|
|
Object.setPrototypeOf(MsgWorkerMessage, MsgWorker.prototype);
|
|
|
|
switch(MsgWorkerMessage.command){
|
|
case 'ws:init':
|
|
let data = MsgWorkerMessage.data();
|
|
// add character specific port (for broadcast) to individual ports (tabs)
|
|
addPort(port, data.characterId);
|
|
initSocket(data.uri);
|
|
break;
|
|
case 'ws:send':
|
|
let MsgSocket = {
|
|
task: MsgWorkerMessage.task(),
|
|
load: MsgWorkerMessage.data()
|
|
};
|
|
|
|
socket.send(JSON.stringify(MsgSocket));
|
|
break;
|
|
case 'ws:close':
|
|
// closeSocket();
|
|
break;
|
|
}
|
|
}, false);
|
|
|
|
port.start();
|
|
}, false); |