Merge pull request #3297 from FinnStutzenstein/Issue3295

improved reconnect handling if the server was flushed (fixed #3295)
This commit is contained in:
Emanuel Schütze 2017-06-16 07:56:30 +02:00 committed by GitHub
commit bef986630e
3 changed files with 44 additions and 8 deletions

View File

@ -49,6 +49,7 @@ Core:
- Enhanced performance esp. for server restart and first connection of all
clients by refactoring autoupdate, Collection and AccessPermission [#3223].
- Fixes autoupdate bug for a user without user.can_see_name permission [#3233].
- Improved reconnect handling if the server was flushed [#3297].
Mediafiles:
- Fixed reloading of PDF on page change [#3274]

View File

@ -48,10 +48,11 @@ angular.module('OpenSlidesApp.core', [
'REALM',
'ProjectorID',
'$q',
'$timeout',
'ErrorMessage',
function (DS, REALM, ProjectorID, $q, ErrorMessage) {
function (DS, REALM, ProjectorID, $q, $timeout, ErrorMessage) {
var socket = null;
var recInterval = null;
var retryConnectCallbacks = [];
var websocketProtocol;
if (location.protocol == 'https:') {
@ -69,6 +70,21 @@ angular.module('OpenSlidesApp.core', [
console.error('The constant REALM is not set properly.');
}
/* The callbacks are invoked if the ws connection closed and this factory tries to
* reconnect after 1 second. The callbacks should return a promise. If the promise
* resolves, the retry-process is stopped, so the callback can indicate whether it
* has managed the reconnecting different.*/
var runRetryConnectCallbacks = function () {
var callbackPromises = _.map(retryConnectCallbacks, function (callback) {
return callback();
});
$q.all(callbackPromises).then(function (success) {
ErrorMessage.clearConnectionError();
}, function (error) {
$timeout(runRetryConnectCallbacks, 1000);
});
};
var Autoupdate = {};
Autoupdate.messageReceivers = [];
// We use later a promise to defer the first message of the established ws connection.
@ -78,15 +94,14 @@ angular.module('OpenSlidesApp.core', [
};
Autoupdate.newConnect = function () {
socket = new WebSocket(websocketProtocol + '//' + location.host + websocketPath);
clearInterval(recInterval);
// Make shure the servers state hasn't changed: Send a whoami request. If no users is logged and
// anonymous are deactivated, reboot the client in fact that the server has lost all login information.
socket.onclose = function (event) {
socket = null;
recInterval = setInterval(function () {
Autoupdate.newConnect();
}, 1000);
if (event.code !== 1000) { // 1000 is a normal close, like the close on logout
ErrorMessage.setConnectionError();
}
$timeout(runRetryConnectCallbacks, 1000);
};
socket.onmessage = function (event) {
var dataList = [];
@ -116,6 +131,9 @@ angular.module('OpenSlidesApp.core', [
}
Autoupdate.firstMessageDeferred = $q.defer();
};
Autoupdate.registerRetryConnectCallback = function (callback) {
retryConnectCallbacks.push(callback);
};
return Autoupdate;
}
])

View File

@ -8,13 +8,14 @@ angular.module('OpenSlidesApp.core.start', [])
'$http',
'$rootScope',
'$state',
'$q',
'DS',
'autoupdate',
'operator',
'Group',
'mainMenu',
function($http, $rootScope, $state, DS, autoupdate, operator, Group, mainMenu) {
return {
function($http, $rootScope, $state, $q, DS, autoupdate, operator, Group, mainMenu) {
var OpenSlides = {
bootup: function () {
$rootScope.openslidesBootstrapDone = false;
$http.get('/users/whoami/').then(function (success) {
@ -46,6 +47,22 @@ angular.module('OpenSlidesApp.core.start', [])
this.bootup();
},
};
// We need to 'ping' the server with a get request to whoami, because then we can decide,
// if the server is down or respond with a 403 (this cannot be differentiated with websockets)
autoupdate.registerRetryConnectCallback(function () {
return $http.get('/users/whoami').then(function (success) {
if (success.data.user_id === null && !success.data.guest_enabled) {
OpenSlides.shutdown();
// Redirect to login dialog if user is not logged in.
$state.go('login', {guest_enabled: success.data.guest_enabled});
} else {
autoupdate.newConnect();
}
});
});
return OpenSlides;
}
])