diff --git a/www/messaging.js b/www/messaging.js index 18053ab..3f19eed 100644 --- a/www/messaging.js +++ b/www/messaging.js @@ -1,15 +1,25 @@ function Messaging(modules) { - var ws = new WebSocket(window.location.origin.replace(/^http/, 'ws') + '/play/'); + 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 keepAlivePeriod = 20000; + 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, - send: send, - start: start - } + isOn: isOn, + send: send + }; function get(obj, path, write) { write = write || false; @@ -37,8 +47,16 @@ function Messaging(modules) { } function addEventListener(path, callback) { - var route = get(routes, path, true); - route.callbacks.push(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) { @@ -59,26 +77,51 @@ function Messaging(modules) { log(o); }; - function log(message) { - if(doLog) { - console.log(message); - } - } - - function start() { - ws.addEventListener('message', messageListener); - ws.addEventListener('open', ping); - addEventListener(["Pong"], ping); - addEventListener(["Error"], function(o) {modules.screen.error(o.error);}); - } - 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() {send({tag: "Ping"});}, keepAlivePeriod); + setTimeout(function() { + if(isOn()) { + send({tag: "Ping"}); + } + }, keepAlivePeriod * s); } }