mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-09-23 12:36:21 -04:00
Workaround ServiceWorker hanging after a while by keeping it alive periodically.
The MessageChannel is re-created each time. It prevents the ServiceWorker from being restarted and losing its variables See #145
This commit is contained in:
parent
ca6d5335ea
commit
387af28bcf
@ -35,6 +35,15 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
||||
*/
|
||||
var MAX_SEARCH_RESULT_SIZE = 50;
|
||||
|
||||
/**
|
||||
* The delay (in milliseconds) between two "keepalive" messages
|
||||
* sent to the ServiceWorker (so that it is not stopped by
|
||||
* the browser, and keeps the MessageChannel to communicate
|
||||
* with the application)
|
||||
* @type Integer
|
||||
*/
|
||||
var DELAY_BETWEEN_KEEPALIVE_SERVICEWORKER = 30000;
|
||||
|
||||
/**
|
||||
* @type ZIMArchive
|
||||
*/
|
||||
@ -191,7 +200,6 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
||||
else {
|
||||
setContentInjectionMode('jquery');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
@ -225,6 +233,29 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
||||
}
|
||||
|
||||
var contentInjectionMode;
|
||||
var keepAliveServiceWorkerHandle;
|
||||
|
||||
/**
|
||||
* Send an 'init' message to the ServiceWorker with a new MessageChannel
|
||||
* to initialize it, or to keep it alive.
|
||||
* This MessageChannel allows a 2-way communication between the ServiceWorker
|
||||
* and the application
|
||||
*/
|
||||
function initOrKeepAliveServiceWorker() {
|
||||
if (contentInjectionMode === 'serviceworker') {
|
||||
// Create a new messageChannel
|
||||
var tmpMessageChannel = new MessageChannel();
|
||||
tmpMessageChannel.port1.onmessage = handleMessageChannelMessage;
|
||||
// Send the init message to the ServiceWorker, with this MessageChannel as a parameter
|
||||
navigator.serviceWorker.controller.postMessage({'action': 'init'}, [tmpMessageChannel.port2]);
|
||||
messageChannel = tmpMessageChannel;
|
||||
console.log("init message sent to ServiceWorker");
|
||||
// Schedule to do it again regularly to keep the 2-way communication alive.
|
||||
// See https://github.com/kiwix/kiwix-js/issues/145 to understand why
|
||||
clearTimeout(keepAliveServiceWorkerHandle);
|
||||
keepAliveServiceWorkerHandle = setTimeout(initOrKeepAliveServiceWorker, DELAY_BETWEEN_KEEPALIVE_SERVICEWORKER, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given injection mode.
|
||||
@ -256,13 +287,6 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
||||
return;
|
||||
}
|
||||
|
||||
if (!messageChannel) {
|
||||
// Let's create the messageChannel for the 2-way communication
|
||||
// with the Service Worker
|
||||
messageChannel = new MessageChannel();
|
||||
messageChannel.port1.onmessage = handleMessageChannelMessage;
|
||||
}
|
||||
|
||||
if (!isServiceWorkerReady()) {
|
||||
$('#serviceWorkerStatus').html("ServiceWorker API available : trying to register it...");
|
||||
navigator.serviceWorker.register('../service-worker.js').then(function (reg) {
|
||||
@ -275,19 +299,24 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
||||
var serviceWorker = reg.installing || reg.waiting || reg.active;
|
||||
serviceWorker.addEventListener('statechange', function(statechangeevent) {
|
||||
if (statechangeevent.target.state === 'activated') {
|
||||
console.log("try to post an init message to ServiceWorker");
|
||||
navigator.serviceWorker.controller.postMessage({'action': 'init'}, [messageChannel.port2]);
|
||||
console.log("init message sent to ServiceWorker");
|
||||
// Create the MessageChannel
|
||||
// and send the 'init' message to the ServiceWorker
|
||||
initOrKeepAliveServiceWorker();
|
||||
}
|
||||
});
|
||||
if (serviceWorker.state === 'activated') {
|
||||
// Even if the ServiceWorker is already activated,
|
||||
// We need to re-create the MessageChannel
|
||||
// and send the 'init' message to the ServiceWorker
|
||||
// in case it has been stopped and lost its context
|
||||
initOrKeepAliveServiceWorker();
|
||||
}
|
||||
}, function (err) {
|
||||
console.error('error while registering serviceWorker', err);
|
||||
refreshAPIStatus();
|
||||
});
|
||||
} else {
|
||||
console.log("try to re-post an init message to ServiceWorker, to re-enable it in case it was disabled");
|
||||
navigator.serviceWorker.controller.postMessage({'action': 'init'}, [messageChannel.port2]);
|
||||
console.log("init message sent to ServiceWorker");
|
||||
initOrKeepAliveServiceWorker();
|
||||
}
|
||||
}
|
||||
$('input:radio[name=contentInjectionMode]').prop('checked', false);
|
||||
@ -324,7 +353,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// At launch, we try to set the last content injection mode (stored in a cookie)
|
||||
var lastContentInjectionMode = cookies.getItem('lastContentInjectionMode');
|
||||
if (lastContentInjectionMode) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user