2020-01-10 08:36:57 +01:00
|
|
|
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: {}};
|
2020-01-15 18:01:07 +01:00
|
|
|
var messagesQueue = [];
|
2020-01-10 08:36:57 +01:00
|
|
|
var wsHandlers = {
|
2020-01-15 18:01:07 +01:00
|
|
|
open: [function() {on = true; reconnectDelay = 1}, catchUp, ping],
|
2020-01-10 08:36:57 +01:00
|
|
|
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) {
|
2020-01-15 18:01:07 +01:00
|
|
|
if(isOn()) {
|
|
|
|
ws.send(JSON.stringify(o));
|
|
|
|
o.direction = 'client > server';
|
|
|
|
log(o);
|
|
|
|
} else {
|
|
|
|
messagesQueue.push(o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function catchUp() {
|
|
|
|
var messages = messagesQueue;
|
|
|
|
messagesQueue = [];
|
2020-01-16 16:03:34 +01:00
|
|
|
messages.forEach(send);
|
2020-01-10 08:36:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|