UNPKG

doushio

Version:
120 lines (100 loc) 2.67 kB
(function () { var socket, attempts, attemptTimer; window.send = function (msg) { // need deferral or reporting on these lost messages... if (connSM.state != 'synced' && connSM.state != 'syncing') return; if (socket.readyState != 1) return; msg = JSON.stringify(msg); if (DEBUG) console.log('<', msg); socket.send(msg); }; function on_message(e) { if (DEBUG) console.log('>', e.data); var msgs = JSON.parse(e.data); with_dom(function () { for (var i = 0; i < msgs.length; i++) { var msg = msgs[i]; var op = msg.shift(); var type = msg.shift(); if (is_pubsub(type) && op in syncs) syncs[op]++; dispatcher[type](msg, op); } }); } function sync_status(msg, hover) { $('#sync').text(msg).attr('class', hover ? 'error' : ''); } connSM.act('load + start -> conn', function () { sync_status('Connecting...', false); attempts = 0; connect(); }); function connect() { if (window.location.protocol == 'file:') { console.log("Page downloaded locally; refusing to sync."); return; } socket = window.new_socket(attempts); socket.onopen = connSM.feeder('open'); socket.onclose = connSM.feeder('close'); socket.onmessage = on_message; } window.new_socket = function (attempt) { return new SockJS(SOCKET_PATH); }; connSM.act('conn, reconn + open -> syncing', function () { sync_status('Syncing...', false); sessionId = random_id(); send([SYNCHRONIZE, sessionId, BOARD, syncs, BUMP, document.cookie]); }); connSM.act('syncing + sync -> synced', function () { sync_status('Synced.', false); attemptTimer = setTimeout(function () { attempts = 0; }, 10000); }); connSM.act('* + close -> dropped', function (e) { if (DEBUG) console.error('E:', e); if (attemptTimer) { clearTimeout(attemptTimer); attemptTimer = 0; } sync_status('Dropped.', true); attempts++; var n = Math.min(Math.floor(attempts/2), 12); var wait = 500 * Math.pow(1.5, n); // wait maxes out at ~1min setTimeout(connSM.feeder('retry'), wait); }); connSM.act('dropped + retry -> reconn', function () { connect(); /* Don't show this immediately so we don't thrash on network loss */ setTimeout(function () { if (connSM.state == 'reconn') sync_status('Reconnecting...', true); }, 100); }); connSM.act('* + invalid, desynced + close -> desynced', function (msg) { msg = (msg && msg[0]) ? 'Out of sync: ' + msg[0] : 'Out of sync.'; sync_status(msg, true); if (attemptTimer) { clearTimeout(attemptTimer); attemptTimer = 0; } delete socket.onclose; socket.close(); socket = null; }); $(function () { _.defer(connSM.feeder('start')); $(window).focus(function () { setTimeout(connSM.feeder('retry'), 20); }); }); })();