Платформа
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
Версия Workbox
5.0.0-rc.0
Я используюметод workbox-window update()
для запуска проверки обновлений работника сервиса, как описано в проблема рабочей области # 2130 . Этот вопрос также, по-видимому, связан с наблюдениями, сделанными в проблема рабочей области # 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 Dev Tools.
![Stuck waiting](https://i.stack.imgur.com/0xQzn.png)
Пропустить ожидающее сообщение, полученное старымработник службы
Если пользователь подтверждает, что он хочет обновить сообщение SKIP_WAITING
, полученное более старым, активированным определением работника службы.
Вот выдержка из моих журналов, подтверждающая это.
- Записи журнала со стороны приложения / клиента начинаются с префикса «Приложение», за которым следует версия приложения.
- В записи журнала от работника службы добавляется префикс «Service Worker», за которым следует метка даты DOB, уникальная для каждого экземпляра работника службы.
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]
On line
- Пользователь только что нажал кнопку «проверить наличие обновлений».
- В
2019-11-05 @ 15:23:14
была обнаружена новая версия работника сервиса, и она анализируется. Мы назовем это SWv2. - Workbox загружен SWv2.
- SWv2
install
обработчик событий выполнен. - Окно Workbox
externalinstalled
обработчик событий выполнен. - Выполнен обработчик события окна рабочего окна
externalwaiting
. - Обработчик события окна рабочего окна
externalwaiting
отправляет сообщение SKIP_WAITING
с использованием workboxWindow.messageSW()
- Service Workerv1 (загруженный на
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!
А иногда он просто зависает ...
А иногда все просто застревает, когда появляется новая версия работника сервисадоступный. Обработчик событий waiting
или externalwaiting
никогда не запускается.
![Chrome Dev Tools](https://i.stack.imgur.com/EuWDd.png)
Когда это происходит, в консоли не возникает ошибок, и с новой версией сервисного работника все в порядке.
Единственный способ отсоединить вещи - остановить активного работника сервиса, отменить его регистрацию и перезагрузить.
Почему все это имеет значение?
Мне нужно убедиться, что процесс обновления работает безупречно на всех платформах, прежде чем я осмелюсь выпустить это приложение ...
Если пользователь сталкивается с какой-либо из этих проблем, когда я выпускаю обновление, ему будет трудно его получить, и я ничего не могу с этим поделать. Умножается на количество установок == огромная головная боль.
Все это сводится к трем вопросам: В порядке важности:
- Как я могу обработать
externalwaiting
, чтобы новая версия работника службы была загружена и активирована? Как убедиться, что сообщение ожидающего работника службы получает сообщение SKIP_WAITING
? - Почему события жизненного цикла различаются между обычным и внешним вариантами?
- В целях тестирования я каждый раз делаю одно и то же обновление для сервисного работника (новая версия предварительно кэшированного файла).
- Приложение загружено только на одной вкладке.
- Переключение с простых событий на внешние кажется случайным.
- Почему процесс иногда застревает до фазы ожидания жизненного цикла и что я могу с этим сделать?