平台
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
工作箱版本
5.0.0-rc.0
我正在使用工作箱窗口update()
方法来触发服务工作者更新检查,如workbox issue #2130中所述。这个问题似乎也与workbox issue #2301中的观察有关。
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/5.0.0-rc.0/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
// Grab the update button from the UI using jQuery and add a listener to it.
$('#update-button').on('click', function () {
wb.update();
});
....
}
</script>
如果找到更新,则将加载新的服务工作程序并进入等待状态。我监听了此事件(waiting
和externalwaiting
都在两种情况下都做同样的事情),并询问用户是否要立即或稍后安装更新。
function handleWaiting(wb) {
if (confirm("An update is available for this app. Install now?")) {
wb.messageSW({type: 'SKIP_WAITING'});
}
}
wb.addEventListener('waiting', event => {
handleWaiting(wb);
});
wb.addEventListener('externalwaiting', event => {
handleWaiting(wb);
});
在大多数情况下,会触发waiting
事件,如果用户接受更新,则会激活服务工作者,我们可以重新加载页面以完成更新过程:
function handleActivated(wb, event) {
if (event.isUpdate) {
window.location.reload();
} else {
wb.messageSW({ type: 'CLIENTS_CLAIM' });
}
}
wb.addEventListener('activated', event => {
handleActivated(wb, event);
});
wb.addEventListener('externalactivated', event => {
handleActivated(wb, event);
});
如果触发了waiting
事件,则此过程可以正常进行。
但是如果触发了externalwaiting
事件,则此代码不起作用。新的服务工作者仍处于等待状态,我可以在Chrome开发工具中看到该状态。
旧服务人员收到的跳过等待消息
如果用户确认他们想更新SKIP_WAITING
消息已由较旧的已激活服务工作人员定义接收到。
这是我的日志摘录,证明了这一点。
01 [Application 0.0.1.2019.11.05-48] Checking for updates...
02 [Service Worker 2019-11-05 @ 15:23:14] <<<<<<<<<<<<<<< STARTING >>>>>>>>>>>>>>>
03 [Service Worker 2019-11-05 @ 15:23:14] Yay! Workbox 5.0.0-rc.0 is loaded ?
04 [Service Worker 2019-11-05 @ 15:23:14] Lifecycle event: [install]
05 [Application 0.0.1.2019.11.05-48] Service Worker lifecycle event: 06 [externalinstalled]
07 [Application 0.0.1.2019.11.05-48] Service Worker lifecycle event: [externalwaiting]
08 [Application 0.0.1.2019.11.05-48] handle waiting...
09 [Service Worker 2019-11-05 @ 15:20:03] Message event: [SKIP_WAITING]
在线
2019-11-05 @ 15:23:14
上发现了新的服务工作者版本,并且正在对其进行解析。我们将其称为SWv2。install
事件处理程序已执行。externalinstalled
事件处理程序。externalwaiting
事件处理程序。externalwaiting
事件处理程序使用SKIP_WAITING
发送workboxWindow.messageSW()
消息2019-11-05 @ 15:20:03
上)收到跳过等待消息。什么都没发生。 SWv2保持等待状态。与普通等待事件的对比
在以下日志中,您可以看到正在等待服务的工作人员收到了SKIP_WAITING
消息:v 2019-11-05 @ 16:07:32
。因此,更新过程成功完成。
[Application 0.0.1.2019.11.05-52] Checking for updates...
[Service Worker 2019-11-05 @ 16:07:32] <<<<<<<<<<<<<<< STARTING >>>>>>>>>>>>>>>
[Service Worker 2019-11-05 @ 16:07:32] Yay! Workbox 5.0.0-rc.0 is loaded ?
[Service Worker 2019-11-05 @ 16:07:32] Lifecycle event: [install]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [installed]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [waiting]
[Application 0.0.1.2019.11.05-52] handle waiting...
[Service Worker 2019-11-05 @ 16:07:32] Message event: [SKIP_WAITING]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [redundant]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [activating]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [controlling]
[Service Worker 2019-11-05 @ 16:07:32] Lifecycle event: [activate]
[Application 0.0.1.2019.11.05-52] Service Worker lifecycle event: [activated]
[Application 0.0.1.2019.11.05-52] Reloading this window...
[Application 0.0.1.2019.11.05-53] <<<<<<<<<<<<<<< STARTING >>>>>>>>>>>>>>>
[Application 0.0.1.2019.11.05-53] Preloading 125 images...
[Application 0.0.1.2019.11.05-53] ServiceWorker registered!
有时它会挂起...
有时,当有新的Service Worker版本可用时,事情就会卡住。 waiting
或externalwaiting
事件处理函数永远不会触发。
这种情况发生时,控制台中没有错误,新版本的Service Worker也没有问题。
解除粘滞状态的唯一方法是停止活动的服务程序,注销并重新加载。
为什么这很重要?
在我敢发布此应用之前,我需要确保更新过程在所有平台上均能正常工作...
如果用户在我发布更新时遇到这些问题之一,他们将很难获取它,而我将无能为力。乘以安装数量==令人头疼。
这全部归结为三个问题: 按照重要性顺序:
externalwaiting
,以便加载并激活新版本的Service Worker?如何确定正在等待服务的工作人员收到了SKIP_WAITING
消息?答案 0 :(得分:0)
请注意,这已在“工作箱”窗口中解决。有更新的高级食谱:
还请注意,此食谱中的代码存在(或曾经存在)问题。有关固定代码,请参见以下问题。