mirror of
https://github.com/kiwix/kiwix-js.git
synced 2025-09-24 04:54:51 -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;
|
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
|
* @type ZIMArchive
|
||||||
*/
|
*/
|
||||||
@ -191,7 +200,6 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
|||||||
else {
|
else {
|
||||||
setContentInjectionMode('jquery');
|
setContentInjectionMode('jquery');
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -225,6 +233,29 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
var contentInjectionMode;
|
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.
|
* Sets the given injection mode.
|
||||||
@ -256,13 +287,6 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
|
|||||||
return;
|
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()) {
|
if (!isServiceWorkerReady()) {
|
||||||
$('#serviceWorkerStatus').html("ServiceWorker API available : trying to register it...");
|
$('#serviceWorkerStatus').html("ServiceWorker API available : trying to register it...");
|
||||||
navigator.serviceWorker.register('../service-worker.js').then(function (reg) {
|
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;
|
var serviceWorker = reg.installing || reg.waiting || reg.active;
|
||||||
serviceWorker.addEventListener('statechange', function(statechangeevent) {
|
serviceWorker.addEventListener('statechange', function(statechangeevent) {
|
||||||
if (statechangeevent.target.state === 'activated') {
|
if (statechangeevent.target.state === 'activated') {
|
||||||
console.log("try to post an init message to ServiceWorker");
|
// Create the MessageChannel
|
||||||
navigator.serviceWorker.controller.postMessage({'action': 'init'}, [messageChannel.port2]);
|
// and send the 'init' message to the ServiceWorker
|
||||||
console.log("init message sent to 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) {
|
}, function (err) {
|
||||||
console.error('error while registering serviceWorker', err);
|
console.error('error while registering serviceWorker', err);
|
||||||
refreshAPIStatus();
|
refreshAPIStatus();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log("try to re-post an init message to ServiceWorker, to re-enable it in case it was disabled");
|
initOrKeepAliveServiceWorker();
|
||||||
navigator.serviceWorker.controller.postMessage({'action': 'init'}, [messageChannel.port2]);
|
|
||||||
console.log("init message sent to ServiceWorker");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$('input:radio[name=contentInjectionMode]').prop('checked', false);
|
$('input:radio[name=contentInjectionMode]').prop('checked', false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user