From 084e0806bc5aff00fc697cb51dee7b4a331e4b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Smodi=C5=A1?= Date: Thu, 8 Oct 2015 19:01:10 +0200 Subject: Adapted to the reworked session handling on the server. Bugfixed the lang setting handling. --- js/codeq/comms.js | 130 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 35 deletions(-) (limited to 'js/codeq/comms.js') diff --git a/js/codeq/comms.js b/js/codeq/comms.js index 54a912f..54f5d24 100644 --- a/js/codeq/comms.js +++ b/js/codeq/comms.js @@ -69,7 +69,8 @@ } }, onMessage = function (data) { - var m, waiter, event, handlers, i, N; + var m, waiter, event, handlers, i, N, + tid, sortedWaiters = [], s; try { m = parseData(data); @@ -79,6 +80,68 @@ return; } + if ('type' in m) { + // system (meta) protocol + switch (m.type) { + case 'sid': + // the peer created or changed our session ID + sid = m.sid; + break; + + case 'reset': + // the server forced us to reset to the login page + // * could not re-register the connection with an existing session ID, username, and password + // * the user logged in elsewhere + s = 'The server forced us to disconnect'; + if (typeof m.message === 'string') s += ': ' + m.message; + codeq.reset(s); + return; + + default: + codeq.log.warn('Unknown system message type: ' + m.type); + } + if (!connected) { + if (sid !== null) { + // our connection registration was successful + connected = true; + if (connectPromise) { + // manual connect + connectPromise.resolve(); + connectPromise = null; + } + else { + // auto re-connect + } + // resend anything not already sent + for (tid in waiters) { + if (waiters.hasOwnProperty(tid)) { + sortedWaiters.push(waiters[tid]); + } + } + // sort by ascending transaction ID before sending + sortedWaiters.sort(function (a, b) {return a.tid - b.tid;}); + for (i = 0; i < sortedWaiters.length; i++) { + (function (waiter) { + if (!waiter.sent) { + socket.send(JSON.stringify(waiter.packet), function () { + waiter.sent = true; + }); + } + })(sortedWaiters[i]); + } + } + else { + codeq.log.error('Operating outside a session!'); + codeq.reset('Protocol error: server sent a bogus message instead of acknowledging our connection'); + } + } + return; + } + + if (!connected) { + codeq.log.warn('Not in the connected state, but receiving a user message anyway'); + } + if ('tid' in m) { waiter = waiters[m.tid]; if (waiter) { @@ -112,33 +175,9 @@ } }, onConnect = function () { - var tid, sortedWaiters = [], i; - connected = true; - if (connectPromise) { - // manual connect - connectPromise.resolve(); - connectPromise = null; - } - else { - // auto re-connect - } - // resend anything not already sent - for (tid in waiters) { - if (waiters.hasOwnProperty(tid)) { - sortedWaiters.push(waiters[tid]); - } - } - // sort by ascending transaction ID before sending - sortedWaiters.sort(function (a, b) {return a.tid - b.tid;}); - for (i = 0; i < sortedWaiters.length; i++) { - (function (waiter) { - if (!waiter.sent) { - socket.send(JSON.stringify(waiter.packet), function () { - waiter.sent = true; - }); - } - })(sortedWaiters[i]); - } + // register our connection + if (sid === null) socket.send(JSON.stringify({'type': 'create_session'})); + else socket.send(JSON.stringify({'type': 'connect_session', 'sid': sid, 'username': login_username, 'password': login_password})); }, onClose = function () { connected = false; @@ -208,6 +247,21 @@ ajaxDataPrefix = ajaxPrefix + 'data/'; ajaxResPrefix = ajaxPrefix + 'res/'; + // ================================================================================ + // Try to be polite and logout on page close/reload + // ================================================================================ + + window.onbeforeunload = function () { + if (sid) { + // we need to perform an action inside the current iteration of the event loop + // so no fancy promises etc., just the raw AJAX request + $.ajax({ + type: 'GET', + url: '/ws/logout?sid=' + sid + '&t=' + Date.now() + }); + } + }; + // ================================================================================ // This module's API methods // ================================================================================ @@ -245,7 +299,8 @@ return deferred.promise; }, - 'disconnect': function () { + 'disconnect': function (reason) { // reason is optional + var tid; if (socket) { socket.off('open', onConnect); socket.off('close', onClose); @@ -264,6 +319,13 @@ } login_password = null; // manual disconnect will prevent auto-login sid = null; + // reject any outstanding promises + for (tid in waiters) { + if (waiters.hasOwnProperty(tid)) { + waiters[id].promise.reject(new Error(reason || 'Forced disconnect')); + delete waiters[tid]; + } + } }, 'send': function (packet) { return Q.Promise(function (resolve, reject, notify) { @@ -321,7 +383,7 @@ }, 'updateSettings': function (new_settings){ - return this.send({'action': 'settings', 'sid': sid, 'settings': new_settings}); + return this.send({'action': 'update_settings', 'settings': new_settings}); }, sendActivity: function commsSendActivity (trace, solution, problem_id) { @@ -358,12 +420,10 @@ return this.send(json); }, - getProblem: function commsGetProblem (language, problem_group, problem) { + getCurrentSolution: function commsGetCurrentSolution (problem_id) { return this.send({ - 'action': 'get_problem', - 'language': language, - 'problem_group': problem_group, - 'problem': problem + 'action': 'get_current_solution', + 'problem_id': problem_id }); }, -- cgit v1.2.1