Index: lams_learning/web/includes/javascript/presence.js
===================================================================
RCS file: /usr/local/cvsroot/lams_learning/web/includes/javascript/presence.js,v
diff -u -r1.4.2.5 -r1.4.2.6
--- lams_learning/web/includes/javascript/presence.js 8 Nov 2016 02:43:08 -0000 1.4.2.5
+++ lams_learning/web/includes/javascript/presence.js 24 May 2017 05:42:25 -0000 1.4.2.6
@@ -72,7 +72,8 @@
if (listing.length == 0){
// create listing div
var listingDiv = $('
'
+ + '" onClick="javascript:roster.handleUserClicked('
+ + localId + ');" class="presenceListing">'
+ createPresenceListing(nick, tag)
+ '
');
@@ -90,62 +91,91 @@
},
// 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 @@
};
presenceWebsocket.send(JSON.stringify(data));
+
+ // reset ping timer
+ clearTimeout(presenceWebsocketPingTimeout);
+ presenceWebsocketPingFunc(true);
}
/* ******* Click handlers ******* */