webclient/js/Messaging.js

139 lines
2.9 KiB
JavaScript

import error as popError from GUI.Screen;
var wsLocation = window.location.origin.replace(/^http/, 'ws') + '/play/';
var ws;
var debug = getParameters().debug;
var doLog = debug != undefined && debug.match(/^(?:1|t(?:rue)?|v(?:rai)?)$/i);
var on = false;
var s = 1000; /* ms */
var keepAlivePeriod = 20;
var reconnectDelay = 1;
var routes = {callbacks: [], children: {}};
var messagesQueue = [];
var wsHandlers = {
open: [function() {on = true; reconnectDelay = 1}, catchUp, ping],
close: [function() {on = false;}, reconnect]
};
init();
return {
addEventListener: addEventListener,
isOn: isOn,
send: send
};
function get(obj, path, write) {
write = write || false;
if(path.length < 1) {
return obj;
} else {
if(obj.children[path[0]] == undefined && write) {
obj.children[path[0]] = {callbacks: [], children: {}};
}
if(obj.children[path[0]] != undefined) {
return get(obj.children[path[0]], path.slice(1), write);
} else {
return null;
}
}
}
function getParameters() {
var o = {};
window.location.search.substr(1).split('&').forEach(function(s) {
var t = s.split('=');
o[t[0]] = t[1];
});
return o;
}
function addEventListener(path, callback) {
if(Array.isArray(path)) {
var route = get(routes, path, true);
route.callbacks.push(callback);
} else {
if(wsHandlers[path] != undefined) {
wsHandlers[path].push(callback);
} else {
log('Unsupported websocket event "' + path + '"');
}
}
}
function messageListener(event) {
var o = JSON.parse(event.data);
var path = [];
var tmp = o;
while(tmp != undefined && tmp.tag != undefined) {
path.push(tmp.tag);
tmp = tmp.message;
}
var route = get(routes, path);
if(route != undefined && route.callbacks != undefined) {
route.callbacks.forEach(function(f) {f(o);});
} else {
console.log("No route found for " + event.data);
}
o.direction = 'client < server';
log(o);
};
function send(o) {
if(isOn()) {
ws.send(JSON.stringify(o));
o.direction = 'client > server';
log(o);
} else {
messagesQueue.push(o);
}
}
function catchUp() {
var messages = messagesQueue;
messagesQueue = [];
messagesQueue.forEach(send);
}
function log(message) {
if(doLog) {
console.log(message);
}
}
function init() {
connect();
addEventListener(["Pong"], ping);
addEventListener(["Error"], function(o) {popError(o.error);});
}
function connect() {
ws = new WebSocket(window.location.origin.replace(/^http/, 'ws') + '/play/');
ws.addEventListener('message', messageListener);
ws.addEventListener('open', function(e) {
wsHandlers.open.forEach(function(handler) {handler(e);});
});
ws.addEventListener('close', function(e) {
wsHandlers.close.forEach(function(handler) {handler(e);});
});
}
function reconnect() {
setTimeout(connect, reconnectDelay * s);
if(reconnectDelay < 16) {
reconnectDelay *= 2;
}
}
function isOn() {
return on;
}
function ping() {
setTimeout(function() {
if(isOn()) {
send({tag: "Ping"});
}
}, keepAlivePeriod * s);
}