receptor/src/socket.js
2018-03-10 09:48:10 -05:00

72 lines
1.6 KiB
JavaScript

import { dispatch } from './store';
import { subscribe, unsubscribe } from './actions/subscribe';
let ws;
let serial = 0;
let transactions = {};
let connected = false;
let queue = [];
const getURI = ({ uri, password }) => `${uri}${password ?
`?password=${encodeURIComponent(password)}` : ''}`;
export default function ws_send(type, body, callback = null, __serial = null) {
const _serial = __serial !== null ? __serial : serial++;
if (callback) {
transactions[_serial] = callback;
}
const obj = {
type,
serial: _serial,
...body
};
const msg = JSON.stringify(obj);
console.log("->", type, obj);
if (!connected) {
queue.push(msg);
} else {
ws.send(msg);
}
return _serial;
}
function _resources_removed(msg) {
dispatch(unsubscribe(...msg.ids));
dispatch(msg);
}
const handlers = {
RESOURCES_EXTANT: msg => dispatch(subscribe(...msg.ids)),
UPDATE_RESOURCES: msg => dispatch(msg),
RESOURCES_REMOVED: msg => _resources_removed(msg),
};
function ws_recv(e) {
const msg = JSON.parse(e.data);
console.log("<-", msg.type, msg);
const cb = transactions[msg.serial];
cb && cb(msg);
const handler = handlers[msg.type];
handler && handler(msg);
}
export function ws_init(uri, open, close) {
ws = new WebSocket(getURI(uri));
ws.addEventListener("open", () => {
connected = true;
open.apply(this, arguments);
while (queue.length > 0) {
ws.send(queue.pop());
}
});
ws.addEventListener("message", ws_recv);
ws.addEventListener("close", () => {
connected = false;
close.apply(this, arguments);
});
}
export function ws_disconnect() {
ws.close();
}