2018-05-31 12:37:57 -04:00
|
|
|
import * as _ from 'lodash';
|
2018-05-30 09:34:33 -04:00
|
|
|
import { JSONMessage } from '//helpers/web-socket';
|
|
|
|
|
2018-05-31 12:37:57 -04:00
|
|
|
export class WSCache {
|
2018-05-30 09:34:33 -04:00
|
|
|
constructor (ws) {
|
2018-05-31 12:37:57 -04:00
|
|
|
this.ws = ws;
|
2018-05-30 09:34:33 -04:00
|
|
|
|
|
|
|
this.ws.addEventListener('message', this.onWebSocketMessage);
|
|
|
|
this.ws.addEventListener('close', this.onWebSocketClose);
|
2018-05-30 10:02:55 -04:00
|
|
|
this.ws.addEventListener('error', console.error);
|
2018-05-30 09:34:33 -04:00
|
|
|
|
|
|
|
// Websocket channels
|
|
|
|
// These hold previous messages if they are needed later
|
|
|
|
this.slots = {
|
|
|
|
'default': [],
|
2018-05-31 12:37:57 -04:00
|
|
|
};
|
2018-05-30 09:34:33 -04:00
|
|
|
|
|
|
|
// Send messages
|
|
|
|
this.sent = {
|
|
|
|
'default': [],
|
2018-05-31 12:37:57 -04:00
|
|
|
};
|
2018-05-30 09:34:33 -04:00
|
|
|
|
|
|
|
// Subscribers
|
|
|
|
this.listeners = {
|
|
|
|
'default': [console.info],
|
2018-05-31 12:37:57 -04:00
|
|
|
'server-log': [console.dir],
|
|
|
|
};
|
2018-05-30 09:34:33 -04:00
|
|
|
|
|
|
|
_.bindAll(this, [
|
|
|
|
'onWebSocketClose',
|
|
|
|
'onWebSocketMessage',
|
|
|
|
'publish',
|
|
|
|
'send',
|
|
|
|
'sendJSON',
|
|
|
|
'subscribe',
|
2018-05-31 12:37:57 -04:00
|
|
|
]);
|
2018-05-30 09:34:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
onWebSocketClose () {
|
|
|
|
console.info('WebSocket closed');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback for receiving a websocket message
|
|
|
|
*
|
|
|
|
* @param {mixed} message
|
|
|
|
*/
|
|
|
|
onWebSocketMessage (message) {
|
|
|
|
try {
|
|
|
|
const messageObject = JSON.parse(message.data);
|
2018-05-31 12:37:57 -04:00
|
|
|
WSCache.instance.publish(messageObject[0], messageObject[1]);
|
2018-05-30 09:34:33 -04:00
|
|
|
} catch (e) {
|
2018-05-31 12:37:57 -04:00
|
|
|
WSCache.instance.publish('default', message.data);
|
2018-05-30 09:34:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Send a recieved websocket message to the appropriate listener(s)
|
|
|
|
*
|
|
|
|
* @param {string} slot
|
|
|
|
* @param {mixed} data
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
publish (slot, data) {
|
|
|
|
if (!this.listeners[slot] || data === undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.slots[slot].push(data);
|
|
|
|
|
|
|
|
this.listeners[slot].forEach(listener => {
|
2018-05-31 12:37:57 -04:00
|
|
|
listener(data);
|
2018-05-30 09:34:33 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a message to the websocket server
|
|
|
|
*
|
|
|
|
* @param {mixed} message
|
|
|
|
*/
|
|
|
|
send (message) {
|
|
|
|
this.sent['default'].push(message);
|
|
|
|
|
|
|
|
return this.ws.send(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Send a JSON-encoded message to the websocket server
|
|
|
|
*
|
|
|
|
* @param {string} slot
|
|
|
|
* @param {mixed} data
|
|
|
|
*/
|
|
|
|
sendJSON (slot, data = {}) {
|
|
|
|
const sentSlots = Object.keys(this.sent);
|
|
|
|
|
|
|
|
if (!sentSlots.includes(slot)) {
|
|
|
|
this.sent[slot] = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
this.sent[slot].push(data);
|
|
|
|
|
|
|
|
return this.ws.send(JSONMessage(slot, data));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subscribe to a websocket message type
|
|
|
|
*
|
|
|
|
* Returns an object with a `unsubscribe` method
|
|
|
|
*
|
|
|
|
* @param {string} slot
|
|
|
|
* @param {function} cb
|
|
|
|
*/
|
|
|
|
subscribe (slot, cb) {
|
|
|
|
const slots = Object.keys(this.slots);
|
|
|
|
// Create the slots and listener arrays
|
|
|
|
if (!slots.includes(slot)) {
|
|
|
|
this.slots[slot] = [];
|
|
|
|
this.listeners[slot] = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
const listenerIndex = this.listeners[slot].push(cb) -1;
|
|
|
|
|
|
|
|
return {
|
|
|
|
remove: () => {
|
|
|
|
delete this.listeners[slot][listenerIndex];
|
2018-05-31 12:37:57 -04:00
|
|
|
},
|
|
|
|
};
|
2018-05-30 09:34:33 -04:00
|
|
|
}
|
|
|
|
}
|
2018-05-31 12:37:57 -04:00
|
|
|
WSCache.instance = null;
|
|
|
|
|
|
|
|
export function createWsCache () {
|
|
|
|
if (WSCache.instance === null) {
|
|
|
|
const ws = new WebSocket('ws://localhost:65432/');
|
|
|
|
const instance = new WSCache(ws);
|
|
|
|
WSCache.instance = instance;
|
|
|
|
return instance;
|
|
|
|
}
|
2018-05-30 09:34:33 -04:00
|
|
|
|
2018-05-31 12:37:57 -04:00
|
|
|
return WSCache.instance;
|
|
|
|
}
|