From 7cb18d1521c69062337439737a624a60a27013d4 Mon Sep 17 00:00:00 2001 From: MarcinCieslak Date: Wed, 24 May 2017 05:42:34 +0000 Subject: [PATCH] LDEV-4332: Send websocket ping after 3 minutes of idleness so the connection does not get cut because of idle timeout. --- lams_admin/web/WEB-INF/tags/Page.tag | 33 ++++- lams_central/web/WEB-INF/tags/Page.tag | 32 +++- lams_gradebook/web/WEB-INF/tags/Page.tag | 78 ++++++---- lams_learning/web/WEB-INF/tags/Page.tag | 79 ++++++---- .../web/includes/javascript/presence.js | 140 +++++++++++------- lams_monitoring/web/WEB-INF/tags/Page.tag | 79 ++++++---- .../web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_bbb/web/WEB-INF/tags/Page.tag | 33 ++++- .../web/actions/LearningWebsocketServer.java | 5 +- lams_tool_chat/web/WEB-INF/tags/Page.tag | 79 ++++++---- .../web/includes/javascript/learning.js | 42 ++++-- lams_tool_daco/web/WEB-INF/tags/Page.tag | 79 ++++++---- lams_tool_forum/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_gmap/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_images/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_imscc/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_kaltura/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_lamc/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_laqa/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_larsrc/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_leader/web/WEB-INF/tags/Page.tag | 33 ++++- .../web/pages/learning/leaderselection.jsp | 23 ++- lams_tool_mindmap/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_nb/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_notebook/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_pixlr/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_preview/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_sbmt/web/WEB-INF/tags/Page.tag | 33 ++++- .../web/action/LearningWebsocketServer.java | 9 -- lams_tool_scratchie/web/WEB-INF/tags/Page.tag | 33 ++++- .../web/pages/learning/questionlist.jsp | 37 ++++- .../web/actions/LearningWebsocketServer.java | 5 + lams_tool_scribe/web/WEB-INF/tags/Page.tag | 33 ++++- .../web/pages/learning/scribe.jsp | 37 ++++- .../web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_survey/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_task/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_vote/web/WEB-INF/tags/Page.tag | 33 ++++- lams_tool_wiki/web/WEB-INF/tags/Page.tag | 33 ++++- lams_www/web/WEB-INF/tags/Page.tag | 33 ++++- 40 files changed, 1225 insertions(+), 357 deletions(-) diff --git a/lams_admin/web/WEB-INF/tags/Page.tag b/lams_admin/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_admin/web/WEB-INF/tags/Page.tag +++ b/lams_admin/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_central/web/WEB-INF/tags/Page.tag b/lams_central/web/WEB-INF/tags/Page.tag index 4b437dc1edf..9d6968528c6 100644 --- a/lams_central/web/WEB-INF/tags/Page.tag +++ b/lams_central/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -168,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_gradebook/web/WEB-INF/tags/Page.tag b/lams_gradebook/web/WEB-INF/tags/Page.tag index c9e7e0e90ea..9d6968528c6 100644 --- a/lams_gradebook/web/WEB-INF/tags/Page.tag +++ b/lams_gradebook/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -146,6 +163,37 @@ } $('#sidebar').show(); } + + function initCommandWebsocket(){ + // it is not an obvious place to init the websocket, but we need lesson ID + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + + commandWebsocket.onclose = function(e){ + if (e.code === 1006) { + // maybe iPad went into sleep mode? + // we need this websocket working, so init it again + initCommandWebsocket(); + } + }; + // when the server pushes new commands + commandWebsocket.onmessage = function(e){ + // read JSON object + var command = JSON.parse(e.data); + if (command.message) { + alert(command.message); + } + if (command.redirectURL) { + window.location.href = command.redirectURL; + } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); + }; + } $(document).ready(function() { var showControlBar = 1; // 0/1/2 none/full/keep space @@ -203,27 +251,7 @@ }); } - // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - - commandWebsocket.onclose = function(e){ - if (e.code === 1006) { - // maybe iPad went into sleep mode? - // we need this websocket working, so init it again - initCommandWebsocket(); - } - }; - // when the server pushes new commands - commandWebsocket.onmessage = function(e){ - // read JSON object - var command = JSON.parse(e.data); - if (command.message) { - alert(command.message); - } - if (command.redirectURL) { - window.location.href = command.redirectURL; - } - }; + initCommandWebsocket(); } }); } @@ -347,7 +375,3 @@ - - - - \ No newline at end of file diff --git a/lams_learning/web/WEB-INF/tags/Page.tag b/lams_learning/web/WEB-INF/tags/Page.tag index c8089be4550..9d6968528c6 100644 --- a/lams_learning/web/WEB-INF/tags/Page.tag +++ b/lams_learning/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -146,6 +163,37 @@ } $('#sidebar').show(); } + + function initCommandWebsocket(){ + // it is not an obvious place to init the websocket, but we need lesson ID + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + + commandWebsocket.onclose = function(e){ + if (e.code === 1006) { + // maybe iPad went into sleep mode? + // we need this websocket working, so init it again + initCommandWebsocket(); + } + }; + // when the server pushes new commands + commandWebsocket.onmessage = function(e){ + // read JSON object + var command = JSON.parse(e.data); + if (command.message) { + alert(command.message); + } + if (command.redirectURL) { + window.location.href = command.redirectURL; + } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); + }; + } $(document).ready(function() { var showControlBar = 1; // 0/1/2 none/full/keep space @@ -203,28 +251,7 @@ }); } - // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - - commandWebsocket.onclose = function(e){ - if (e.code === 1006) { - // maybe iPad went into sleep mode? - // we need this websocket working, so init it again - initCommandWebsocket(); - } - }; - - // when the server pushes new commands - commandWebsocket.onmessage = function(e){ - // read JSON object - var command = JSON.parse(e.data); - if (command.message) { - alert(command.message); - } - if (command.redirectURL) { - window.location.href = command.redirectURL; - } - }; + initCommandWebsocket(); } }); } @@ -348,7 +375,3 @@ - - - - \ No newline at end of file diff --git a/lams_learning/web/includes/javascript/presence.js b/lams_learning/web/includes/javascript/presence.js index bbb6eb277c5..e0358eeecee 100644 --- a/lams_learning/web/includes/javascript/presence.js +++ b/lams_learning/web/includes/javascript/presence.js @@ -72,7 +72,8 @@ $(document).ready(function (){ if (listing.length == 0){ // create listing div var listingDiv = $('
' + + '" onClick="javascript:roster.handleUserClicked(' + + localId + ');" class="presenceListing">' + createPresenceListing(nick, tag) + '
'); @@ -90,62 +91,91 @@ $(document).ready(function (){ }, // init the connection with server using server URL but with different protocol - presenceWebsocket = new WebSocket(APP_URL.replace('http', 'ws') + 'presenceChatWebsocket?lessonID=' + lessonId + - '&imEnabled=' + presenceImEnabled + '&nickname=' + encodeURIComponent(nickname)); - -// when the server pushes new messages and roster to the learner's browser -presenceWebsocket.onmessage = function(e){ - // create JSON object - var input = JSON.parse(e.data); - if (input.roster) { - roster.updateDisplay(input.roster); - } - - if (input.messages) { - var activeNick = getUserFromTabIndex(presenceChatTabs.tabs('option','active')), - selectedTabTag = nickToTag(activeNick); + presenceWebsocket = new WebSocket(APP_URL.replace('http', 'ws') + 'presenceChatWebsocket?lessonID=' + lessonId + + '&imEnabled=' + presenceImEnabled + + '&nickname=' + encodeURIComponent(nickname)), + presenceWebsocketPingTimeout = null, + presenceWebsocketPingFunc = null; + + presenceWebsocketPingFunc = function(skipPing){ + if (presenceWebsocket.readyState == presenceWebsocket.CLOSING + || presenceWebsocket.readyState == presenceWebsocket.CLOSED){ + location.reload(); + } + + // check and ping every 3 minutes + presenceWebsocketPingTimeout = setTimeout(presenceWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + presenceWebsocket.send("ping"); + } + }; + // set up timer for the first time + presenceWebsocketPingFunc(true); + + presenceWebsocket.onclose = function(e){ + // react only on abnormal close + if (e.code === 1006) { + location.reload(); + } + }; + // when the server pushes new messages and roster to the learner's browser + presenceWebsocket.onmessage = function(e){ + // reset ping timer + clearTimeout(presenceWebsocketPingTimeout); + presenceWebsocketPingFunc(true); + + // create JSON object + var input = JSON.parse(e.data); + if (input.roster) { + roster.updateDisplay(input.roster); + } - jQuery.each(input.messages, function(){ - // which tab are we talking about? - var from = this.to ? (this.from == nickname ? this.to : this.from) : groupChatInfo.nick, - lastMessageUid = roster.lastMessageUids[from] || 0; + if (input.messages) { + var activeNick = getUserFromTabIndex(presenceChatTabs.tabs('option','active')), + selectedTabTag = nickToTag(activeNick); - // are the messages new? - if (this.uid > lastMessageUid) { - var tag = nickToTag(from); - if (tag != selectedTabTag) { - var tab = $("#" + tagToTabLabel(tag)); - if (tab.length == 0) { - // no tab opened yet, create it - tab = addTab(from, tag); - } - - // notify of new message - tab.addClass('presenceTabNewMessage'); - if (tag != groupChatInfo.tag) { - $("#" + tagToListing(tag)).addClass('presenceListingNewMessage'); - } - } + jQuery.each(input.messages, function(){ + // which tab are we talking about? + var from = this.to ? (this.from == nickname ? this.to : this.from) : groupChatInfo.nick, + lastMessageUid = roster.lastMessageUids[from] || 0; - roster.lastMessageUids[from] = this.uid; - var messageArea = $("#" + (nickToMessageArea(from))); - messageArea.append(generateMessageHTML(this.from, this.message, this.dateSent)); - messageArea.scrollTop(messageArea.prop('scrollHeight')); - } - }); - } - - // remove conversation tabs with learners who are gone - $('li a', presenceChatTabs).each(function() { - var nick = $(this).text(); - if (nick != groupChatInfo.nick && !roster.users[nick]) { - var tag = $(this).attr('href'); - $(tag).remove(); - $(this).parent().remove(); - presenceChatTabs.tabs('refresh'); + // are the messages new? + if (this.uid > lastMessageUid) { + var tag = nickToTag(from); + if (tag != selectedTabTag) { + var tab = $("#" + tagToTabLabel(tag)); + if (tab.length == 0) { + // no tab opened yet, create it + tab = addTab(from, tag); + } + + // notify of new message + tab.addClass('presenceTabNewMessage'); + if (tag != groupChatInfo.tag) { + $("#" + tagToListing(tag)).addClass('presenceListingNewMessage'); + } + } + + roster.lastMessageUids[from] = this.uid; + var messageArea = $("#" + (nickToMessageArea(from))); + messageArea.append(generateMessageHTML(this.from, this.message, this.dateSent)); + messageArea.scrollTop(messageArea.prop('scrollHeight')); + } + }); } - }); -}; + + // remove conversation tabs with learners who are gone + $('li a', presenceChatTabs).each(function() { + var nick = $(this).text(); + if (nick != groupChatInfo.nick && !roster.users[nick]) { + var tag = $(this).attr('href'); + $(tag).remove(); + $(this).parent().remove(); + presenceChatTabs.tabs('refresh'); + } + }); + }; }); @@ -276,6 +306,10 @@ function sendMessage(receiver) { }; presenceWebsocket.send(JSON.stringify(data)); + + // reset ping timer + clearTimeout(presenceWebsocketPingTimeout); + presenceWebsocketPingFunc(true); } /* ******* Click handlers ******* */ diff --git a/lams_monitoring/web/WEB-INF/tags/Page.tag b/lams_monitoring/web/WEB-INF/tags/Page.tag index c8089be4550..9d6968528c6 100644 --- a/lams_monitoring/web/WEB-INF/tags/Page.tag +++ b/lams_monitoring/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -146,6 +163,37 @@ } $('#sidebar').show(); } + + function initCommandWebsocket(){ + // it is not an obvious place to init the websocket, but we need lesson ID + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + + commandWebsocket.onclose = function(e){ + if (e.code === 1006) { + // maybe iPad went into sleep mode? + // we need this websocket working, so init it again + initCommandWebsocket(); + } + }; + // when the server pushes new commands + commandWebsocket.onmessage = function(e){ + // read JSON object + var command = JSON.parse(e.data); + if (command.message) { + alert(command.message); + } + if (command.redirectURL) { + window.location.href = command.redirectURL; + } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); + }; + } $(document).ready(function() { var showControlBar = 1; // 0/1/2 none/full/keep space @@ -203,28 +251,7 @@ }); } - // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - - commandWebsocket.onclose = function(e){ - if (e.code === 1006) { - // maybe iPad went into sleep mode? - // we need this websocket working, so init it again - initCommandWebsocket(); - } - }; - - // when the server pushes new commands - commandWebsocket.onmessage = function(e){ - // read JSON object - var command = JSON.parse(e.data); - if (command.message) { - alert(command.message); - } - if (command.redirectURL) { - window.location.href = command.redirectURL; - } - }; + initCommandWebsocket(); } }); } @@ -348,7 +375,3 @@ - - - - \ No newline at end of file diff --git a/lams_tool_assessment/web/WEB-INF/tags/Page.tag b/lams_tool_assessment/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_assessment/web/WEB-INF/tags/Page.tag +++ b/lams_tool_assessment/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_bbb/web/WEB-INF/tags/Page.tag b/lams_tool_bbb/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_bbb/web/WEB-INF/tags/Page.tag +++ b/lams_tool_bbb/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java b/lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java index 05a0e0d42ca..f149a467f76 100644 --- a/lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java +++ b/lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningWebsocketServer.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.util.Date; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -304,6 +303,10 @@ public void receiveMessage(String input, Session session) throws JSONException { if (StringUtils.isBlank(input)) { return; } + if (input.equalsIgnoreCase("ping")) { + // just a ping every few minutes + return; + } JSONObject messageJSON = new JSONObject(input); String message = messageJSON.getString("message"); if (StringUtils.isBlank(message)) { diff --git a/lams_tool_chat/web/WEB-INF/tags/Page.tag b/lams_tool_chat/web/WEB-INF/tags/Page.tag index c8089be4550..9d6968528c6 100644 --- a/lams_tool_chat/web/WEB-INF/tags/Page.tag +++ b/lams_tool_chat/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -146,6 +163,37 @@ } $('#sidebar').show(); } + + function initCommandWebsocket(){ + // it is not an obvious place to init the websocket, but we need lesson ID + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + + commandWebsocket.onclose = function(e){ + if (e.code === 1006) { + // maybe iPad went into sleep mode? + // we need this websocket working, so init it again + initCommandWebsocket(); + } + }; + // when the server pushes new commands + commandWebsocket.onmessage = function(e){ + // read JSON object + var command = JSON.parse(e.data); + if (command.message) { + alert(command.message); + } + if (command.redirectURL) { + window.location.href = command.redirectURL; + } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); + }; + } $(document).ready(function() { var showControlBar = 1; // 0/1/2 none/full/keep space @@ -203,28 +251,7 @@ }); } - // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - - commandWebsocket.onclose = function(e){ - if (e.code === 1006) { - // maybe iPad went into sleep mode? - // we need this websocket working, so init it again - initCommandWebsocket(); - } - }; - - // when the server pushes new commands - commandWebsocket.onmessage = function(e){ - // read JSON object - var command = JSON.parse(e.data); - if (command.message) { - alert(command.message); - } - if (command.redirectURL) { - window.location.href = command.redirectURL; - } - }; + initCommandWebsocket(); } }); } @@ -348,7 +375,3 @@ - - - - \ No newline at end of file diff --git a/lams_tool_chat/web/includes/javascript/learning.js b/lams_tool_chat/web/includes/javascript/learning.js index efd4783c5d3..13dd414c3c5 100644 --- a/lams_tool_chat/web/includes/javascript/learning.js +++ b/lams_tool_chat/web/includes/javascript/learning.js @@ -22,15 +22,39 @@ $(document).ready(function() { // only Monitor can send a personal message var selectedUser = null, // init the connection with server using server URL but with different protocol - chatToolWebsocket = new WebSocket(APP_URL.replace('http', 'ws') + 'learningWebsocket?toolSessionID=' + TOOL_SESSION_ID); + chatWebsocket = new WebSocket(APP_URL.replace('http', 'ws') + + 'learningWebsocket?toolSessionID=' + TOOL_SESSION_ID), + chatWebsocketPingTimeout = null, + chatWebsocketPingFunc = null; - chatToolWebsocket.onclose = function(e){ + chatWebsocketPingFunc = function(skipPing){ + if (chatWebsocket.readyState == chatWebsocket.CLOSING + || chatWebsocket.readyState == chatWebsocket.CLOSED){ + location.reload(); + } + + // check and ping every 3 minutes + chatWebsocketPingTimeout = setTimeout(chatWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + chatWebsocket.send("ping"); + } + }; + // set up timer for the first time + chatWebsocketPingFunc(true); + + chatWebsocket.onclose = function(e){ + // react only on abnormal close if (e.code === 1006) { location.reload(); } }; - chatToolWebsocket.onmessage = function(e){ + chatWebsocket.onmessage = function(e){ + // reset ping timer + clearTimeout(chatWebsocketPingTimeout); + chatWebsocketPingFunc(true); + // create JSON object var input = JSON.parse(e.data); // clear old messages @@ -72,10 +96,6 @@ $(document).ready(function() { }); } - - chatToolWebsocket.onerror = function(e){ - alert("Error estabilishing connection to server: " + e.data); - } function userSelected(userDiv) { var userDivContent = userDiv.html(); @@ -108,7 +128,11 @@ $(document).ready(function() { }; // send it to server - chatToolWebsocket.send(JSON.stringify(output)); + chatWebsocket.send(JSON.stringify(output)); + + // reset ping timer + clearTimeout(chatWebsocketPingTimeout); + chatWebsocketPingFunc(true); } }); @@ -119,4 +143,4 @@ function getColour(nick) { charSum += nick.charCodeAt(i); } return PALETTE[charSum % (PALETTE.length)]; -} +} \ No newline at end of file diff --git a/lams_tool_daco/web/WEB-INF/tags/Page.tag b/lams_tool_daco/web/WEB-INF/tags/Page.tag index c8089be4550..9d6968528c6 100644 --- a/lams_tool_daco/web/WEB-INF/tags/Page.tag +++ b/lams_tool_daco/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -146,6 +163,37 @@ } $('#sidebar').show(); } + + function initCommandWebsocket(){ + // it is not an obvious place to init the websocket, but we need lesson ID + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + + commandWebsocket.onclose = function(e){ + if (e.code === 1006) { + // maybe iPad went into sleep mode? + // we need this websocket working, so init it again + initCommandWebsocket(); + } + }; + // when the server pushes new commands + commandWebsocket.onmessage = function(e){ + // read JSON object + var command = JSON.parse(e.data); + if (command.message) { + alert(command.message); + } + if (command.redirectURL) { + window.location.href = command.redirectURL; + } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); + }; + } $(document).ready(function() { var showControlBar = 1; // 0/1/2 none/full/keep space @@ -203,28 +251,7 @@ }); } - // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - - commandWebsocket.onclose = function(e){ - if (e.code === 1006) { - // maybe iPad went into sleep mode? - // we need this websocket working, so init it again - initCommandWebsocket(); - } - }; - - // when the server pushes new commands - commandWebsocket.onmessage = function(e){ - // read JSON object - var command = JSON.parse(e.data); - if (command.message) { - alert(command.message); - } - if (command.redirectURL) { - window.location.href = command.redirectURL; - } - }; + initCommandWebsocket(); } }); } @@ -348,7 +375,3 @@ - - - - \ No newline at end of file diff --git a/lams_tool_forum/web/WEB-INF/tags/Page.tag b/lams_tool_forum/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_forum/web/WEB-INF/tags/Page.tag +++ b/lams_tool_forum/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_gmap/web/WEB-INF/tags/Page.tag b/lams_tool_gmap/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_gmap/web/WEB-INF/tags/Page.tag +++ b/lams_tool_gmap/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_images/web/WEB-INF/tags/Page.tag b/lams_tool_images/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_images/web/WEB-INF/tags/Page.tag +++ b/lams_tool_images/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_imscc/web/WEB-INF/tags/Page.tag b/lams_tool_imscc/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_imscc/web/WEB-INF/tags/Page.tag +++ b/lams_tool_imscc/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_kaltura/web/WEB-INF/tags/Page.tag b/lams_tool_kaltura/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_kaltura/web/WEB-INF/tags/Page.tag +++ b/lams_tool_kaltura/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_lamc/web/WEB-INF/tags/Page.tag b/lams_tool_lamc/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_lamc/web/WEB-INF/tags/Page.tag +++ b/lams_tool_lamc/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_laqa/web/WEB-INF/tags/Page.tag b/lams_tool_laqa/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_laqa/web/WEB-INF/tags/Page.tag +++ b/lams_tool_laqa/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_larsrc/web/WEB-INF/tags/Page.tag b/lams_tool_larsrc/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_larsrc/web/WEB-INF/tags/Page.tag +++ b/lams_tool_larsrc/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_leader/web/WEB-INF/tags/Page.tag b/lams_tool_leader/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_leader/web/WEB-INF/tags/Page.tag +++ b/lams_tool_leader/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_leader/web/pages/learning/leaderselection.jsp b/lams_tool_leader/web/pages/learning/leaderselection.jsp index 13e2e5857fe..fc43d37f518 100644 --- a/lams_tool_leader/web/pages/learning/leaderselection.jsp +++ b/lams_tool_leader/web/pages/learning/leaderselection.jsp @@ -28,9 +28,28 @@ //init the connection with server using server URL but with different protocol var leaderWebsocket = new WebSocket(''.replace('http', 'ws') - + 'learningWebsocket?toolSessionID=' + ${toolSessionID}); + + 'learningWebsocket?toolSessionID=' + ${toolSessionID}), + leaderWebsocketPingTimeout = null, + leaderWebsocketPingFunc = null; + + leaderWebsocketPingFunc = function(skipPing){ + if (leaderWebsocket.readyState == leaderWebsocket.CLOSING + || leaderWebsocket.readyState == leaderWebsocket.CLOSED){ + location.reload(); + } + + // check and ping every 3 minutes + leaderWebsocketPingTimeout = setTimeout(leaderWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + leaderWebsocket.send("ping"); + } + }; + // set up timer for the first time + leaderWebsocketPingFunc(true); leaderWebsocket.onclose = function(e){ + // react only on abnormal close if (e.code === 1006) { location.reload(); } @@ -38,6 +57,8 @@ // run when the leader has just been selected leaderWebsocket.onmessage = function(e) { + // no need to reset ping timer as the only possible message is page refresh + // create JSON object var input = JSON.parse(e.data); diff --git a/lams_tool_mindmap/web/WEB-INF/tags/Page.tag b/lams_tool_mindmap/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_mindmap/web/WEB-INF/tags/Page.tag +++ b/lams_tool_mindmap/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_nb/web/WEB-INF/tags/Page.tag b/lams_tool_nb/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_nb/web/WEB-INF/tags/Page.tag +++ b/lams_tool_nb/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_notebook/web/WEB-INF/tags/Page.tag b/lams_tool_notebook/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_notebook/web/WEB-INF/tags/Page.tag +++ b/lams_tool_notebook/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_pixlr/web/WEB-INF/tags/Page.tag b/lams_tool_pixlr/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_pixlr/web/WEB-INF/tags/Page.tag +++ b/lams_tool_pixlr/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_preview/web/WEB-INF/tags/Page.tag b/lams_tool_preview/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_preview/web/WEB-INF/tags/Page.tag +++ b/lams_tool_preview/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_sbmt/web/WEB-INF/tags/Page.tag b/lams_tool_sbmt/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_sbmt/web/WEB-INF/tags/Page.tag +++ b/lams_tool_sbmt/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningWebsocketServer.java b/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningWebsocketServer.java index 5b5dddf2d20..4524fa25f92 100644 --- a/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningWebsocketServer.java +++ b/lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/action/LearningWebsocketServer.java @@ -12,7 +12,6 @@ import javax.websocket.CloseReason; import javax.websocket.CloseReason.CloseCodes; import javax.websocket.OnClose; -import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @@ -205,14 +204,6 @@ public void unregisterUser(Session websocket, CloseReason reason) { } } - /** - * Receives a message sent by Learner via a websocket. - */ - @OnMessage - public void receiveRequest(String input, Session websocket) throws JSONException { - log.debug("Received \"" + input + "\" from " + websocket.getUserPrincipal().getName()); - } - /** * The leader finished scratching and also . Non-leaders will have * Finish button displayed. diff --git a/lams_tool_scratchie/web/WEB-INF/tags/Page.tag b/lams_tool_scratchie/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_scratchie/web/WEB-INF/tags/Page.tag +++ b/lams_tool_scratchie/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_scratchie/web/pages/learning/questionlist.jsp b/lams_tool_scratchie/web/pages/learning/questionlist.jsp index 792c4c31b56..03ae36f8763 100644 --- a/lams_tool_scratchie/web/pages/learning/questionlist.jsp +++ b/lams_tool_scratchie/web/pages/learning/questionlist.jsp @@ -29,9 +29,28 @@ //init the connection with server using server URL but with different protocol var scratchieWebsocket = new WebSocket(''.replace('http', 'ws') - + 'learningWebsocket?toolSessionID=' + ${toolSessionID}); + + 'learningWebsocket?toolSessionID=' + ${toolSessionID}), + scratchieWebsocketPingTimeout = null, + scratchieWebsocketPingFunc = null; + + scratchieWebsocketPingFunc = function(skipPing){ + if (scratchieWebsocket.readyState == scratchieWebsocket.CLOSING + || scratchieWebsocket.readyState == scratchieWebsocket.CLOSED){ + location.reload(); + } + + // check and ping every 3 minutes + scratchieWebsocketPingTimeout = setTimeout(scratchieWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + scratchieWebsocket.send("ping"); + } + }; + // set up timer for the first time + scratchieWebsocketPingFunc(true); scratchieWebsocket.onclose = function(e) { + // react only on abnormal close if (e.code === 1006) { location.reload(); } @@ -42,12 +61,6 @@ // create JSON object var input = JSON.parse(e.data); - // leader finished the activity - if (input.close) { - $('#finishButton').show(); - return; - } - //time limit is expired but leader hasn't submitted required notebook/burning questions yet. Non-leaders //will need to refresh the page in order to stop showing them questions page. if (input.pageRefresh) { @@ -55,6 +68,16 @@ return; } + // reset ping timer + clearTimeout(scratchieWebsocketPingTimeout); + scratchieWebsocketPingFunc(true); + + // leader finished the activity + if (input.close) { + $('#finishButton').show(); + return; + } + $.each(input, function(itemUid, answers) { $.each(answers, function(answerUid, isCorrect){ // only updates come via websockets diff --git a/lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java b/lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java index 141c6ed4c6d..a2ad3cd8f6c 100644 --- a/lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java +++ b/lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java @@ -257,6 +257,11 @@ public void receiveRequest(String input, Session websocket) throws JSONException if (StringUtils.isBlank(input)) { return; } + if (input.equalsIgnoreCase("ping")) { + // just a ping every few minutes + return; + } + JSONObject requestJSON = new JSONObject(input); switch (requestJSON.getString("type")) { case "vote": diff --git a/lams_tool_scribe/web/WEB-INF/tags/Page.tag b/lams_tool_scribe/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_scribe/web/WEB-INF/tags/Page.tag +++ b/lams_tool_scribe/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_scribe/web/pages/learning/scribe.jsp b/lams_tool_scribe/web/pages/learning/scribe.jsp index 19ef8a12d56..9e62ca58039 100644 --- a/lams_tool_scribe/web/pages/learning/scribe.jsp +++ b/lams_tool_scribe/web/pages/learning/scribe.jsp @@ -15,13 +15,38 @@ }); //init the connection with server using server URL but with different protocol - var websocket = new WebSocket('${tool}'.replace('http', 'ws') + var scribeWebsocket = new WebSocket('${tool}'.replace('http', 'ws') + 'learningWebsocket?toolSessionID=' + ${scribeSessionDTO.sessionID}), + scribeWebsocketPingTimeout = null, + scribeWebsocketPingFunc = null, agreementPercentageLabel = '', reportSubmitted = ${scribeSessionDTO.reportSubmitted}; + scribeWebsocketPingFunc = function(skipPing){ + if (scribeWebsocket.readyState == scribeWebsocket.CLOSING + || scribeWebsocket.readyState == scribeWebsocket.CLOSED){ + location.reload(); + } + + // check and ping every 3 minutes + scribeWebsocketPingTimeout = setTimeout(scribeWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + scribeWebsocket.send("ping"); + } + }; + // set up timer for the first time + scribeWebsocketPingFunc(true); + + scribeWebsocket.onclose = function(e){ + // react only on abnormal close + if (e.code === 1006) { + location.reload(); + } + }; + // run when the server pushes new reports and vote statistics - websocket.onmessage = function(e) { + scribeWebsocket.onmessage = function(e) { // create JSON object var input = JSON.parse(e.data), agreeButton = $('#agreeButton'); @@ -32,6 +57,10 @@ return; } + // reset ping timer + clearTimeout(scribeWebsocketPingTimeout); + scribeWebsocketPingFunc(true); + // only changed reports will be sent if (input.reports) { $.each(input.reports, function() { @@ -59,7 +88,7 @@ var data = { type : 'vote' }; - websocket.send(JSON.stringify(data)); + scribeWebsocket.send(JSON.stringify(data)); $('#agreeButton').hide(); } @@ -77,7 +106,7 @@ }); }); data.reports = reports; - websocket.send(JSON.stringify(data)); + scribeWebsocket.send(JSON.stringify(data)); reportSubmitted = true; } diff --git a/lams_tool_spreadsheet/web/WEB-INF/tags/Page.tag b/lams_tool_spreadsheet/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_spreadsheet/web/WEB-INF/tags/Page.tag +++ b/lams_tool_spreadsheet/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_survey/web/WEB-INF/tags/Page.tag b/lams_tool_survey/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_survey/web/WEB-INF/tags/Page.tag +++ b/lams_tool_survey/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_task/web/WEB-INF/tags/Page.tag b/lams_tool_task/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_task/web/WEB-INF/tags/Page.tag +++ b/lams_tool_task/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_vote/web/WEB-INF/tags/Page.tag b/lams_tool_vote/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_vote/web/WEB-INF/tags/Page.tag +++ b/lams_tool_vote/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_tool_wiki/web/WEB-INF/tags/Page.tag b/lams_tool_wiki/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_tool_wiki/web/WEB-INF/tags/Page.tag +++ b/lams_tool_wiki/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; } diff --git a/lams_www/web/WEB-INF/tags/Page.tag b/lams_www/web/WEB-INF/tags/Page.tag index 39ba5517b78..9d6968528c6 100644 --- a/lams_www/web/WEB-INF/tags/Page.tag +++ b/lams_www/web/WEB-INF/tags/Page.tag @@ -96,13 +96,30 @@ // it gets initialised along with progress bar commandWebsocket = null, - + commandWebsocketPingTimeout = null, + commandWebsocketPingFunc = null, + bars = { 'learnerMainBar' : { 'containerId' : 'progressBarDiv' } }; - + + commandWebsocketPingFunc = function(skipPing){ + if (commandWebsocket.readyState == commandWebsocket.CLOSING + || commandWebsocket.readyState == commandWebsocket.CLOSED){ + initCommandWebsocket(); + return; + } + + // check and ping every 3 minutes + commandWebsocketPingTimeout = setTimeout(commandWebsocketPingFunc, 3*60*1000); + // initial set up does not send ping + if (!skipPing) { + commandWebsocket.send("ping"); + } + }; + function restartLesson(){ if (confirm(restartLessonConfirmation)) { window.location.href = LEARNING_URL + 'learner.do?method=restartLesson&lessonID=' + lessonId; @@ -149,8 +166,11 @@ function initCommandWebsocket(){ // it is not an obvious place to init the websocket, but we need lesson ID - commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + 'commandWebsocket?lessonID=' + lessonId); - + commandWebsocket = new WebSocket(LEARNING_URL.replace('http', 'ws') + + 'commandWebsocket?lessonID=' + lessonId); + // set up timer for the first time + commandWebsocketPingFunc(true); + commandWebsocket.onclose = function(e){ if (e.code === 1006) { // maybe iPad went into sleep mode? @@ -158,7 +178,6 @@ initCommandWebsocket(); } }; - // when the server pushes new commands commandWebsocket.onmessage = function(e){ // read JSON object @@ -169,6 +188,10 @@ if (command.redirectURL) { window.location.href = command.redirectURL; } + + // reset ping timer + clearTimeout(commandWebsocketPingTimeout); + commandWebsocketPingFunc(true); }; }