function Messaging(modules) { 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 wsHandlers = { open: [function() {on = true; reconnectDelay = 1}, 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) { ws.send(JSON.stringify(o)); o.direction = 'client > server'; log(o); } function log(message) { if(doLog) { console.log(message); } } function init() { connect(); addEventListener(["Pong"], ping); addEventListener(["Error"], function(o) {modules.screen.error(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); } }