Триггер события обновления сервисного работника - PullRequest
0 голосов
/ 31 октября 2019

Перейдя по этой ссылке https://github.com/deanhume/pwa-update-available, Я пытаюсь внедрить обновление сервисного работника, но я сталкиваюсь с такими проблемами, как обновление события не запускается, что, я думаю, связано с дизайном моего приложения, который по сути является SPA, означает, что я всегда нахожусь в index.html, который ведет себя как app-shell, и я толкаю содержимое в области содержимого, в зависимости от того, какая кнопка нажата.

только другая страница - login / index.html

содержимое файла app.js для установки / обновления работника службы выглядит следующим образом:

let newWorker;
          function showUpdateBar() {
            let snackbar = document.getElementById('snackbar');
            snackbar.className = 'show';
          }
          // The click event on the pop up notification
          document.getElementById('reload').addEventListener('click', function(){
            newWorker.postMessage({ action: 'skipWaiting' });
          });
          if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/pwa/sw.js').then(reg => {
              console.log( 'ServiceWorker registration successful with scope: ', registration.scope );
              reg.addEventListener('updatefound', () => {
                // A wild service worker has appeared in reg.installing!
                newWorker = reg.installing;
                newWorker.addEventListener('statechange', () => {
                  // Has network.state changed?
                  switch (newWorker.state) {
                    case 'installed':
                      if (navigator.serviceWorker.controller) {
                        // new update available
                        showUpdateBar();
                      }
                      // No update available
                      break;
                  }
                });
              });
            });
            let refreshing;
            navigator.serviceWorker.addEventListener('controllerchange', function () {
              if (refreshing) return;
              window.location.reload();
              refreshing = true;
            });
          }  

и содержимое файла sw.js выглядит следующим образом:

var cacheName = 'v28';

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(cacheName)
      .then(cache => cache.addAll([
        "/pwa/index.html",
        "/pwa/main.css",
        "/pwa/js/app/app.js",
        "/pwa/js/app/libs/api.js",
        '/pwa/query.js',
        '/pwa/js/libs/localforage.min.js',
        '/pwa/js/libs/utils.js'
      ]))
  );
});



self.addEventListener('message', function (event) {
  if (event.data.action === 'skipWaiting') {
    self.skipWaiting();
  }
});

// Allow sw to control of current page
self.addEventListener('activate', event => {
  console.log('Activating new service worker...');

  const cacheWhitelist = [cacheName];

  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

theчастичное содержимое файла index.html:

<div id="snackbar">A new version of this app is available. Click <a id="reload">here</a> to update.</div>

, поэтому в основном я сталкиваюсь с проблемой запуска обновления, когда я меняю номер версии, например с v28, на v29 и перезагружаю страницу, я получаюподсказка, но я не получаю подсказку, даже когда я выхожу из системы, войдите или выходите и снова открываете приложение.

Как я могу это исправить?

Примечание: PWA - моя прогрессивная папка приложения, яя использую php / yii2 как баckend и не использующий сервер узла или другую инфраструктуру JS.

1 Ответ

1 голос
/ 04 ноября 2019

подпрограмма регистрации работника сервиса, которая запускается у вас, только когда вы загружаете index.html в браузер. Это единственный раз, когда код выполняется.

Если вы периодически не опрашиваете свой сервер или, возможно, не открываете веб-сокет (довольно дорого для этого), вы не будете знать, доступен ли новый сервисный работник. Вы можете попросить пользователя зарегистрироваться для push-уведомлений .... слишком большая головная боль для этого.

Поэтому объединяйте сервер каждые несколько часов или дней для обновления.

Если есть обновление, выможет вызвать подпрограмму обновления.

Я бы поместил логику опроса в реальный код работника сервиса, чтобы он не входил в UI. Если вы SPA, вы уже блокируете поток UI достаточно LOL.

Существует множество способов обработать эту кошку, setTimeout (..., {много секунд}), когда работник службы просыпается от бездействия и т. Д.

Если вы можете сделать запрос HEAD,будет поддерживать сетевой трафик до минимума.

Если есть обновление, вы можете отправить сообщение в UI для обновления работника сервиса.

Это не то, что я бы назвал тривиальным кодом,Я делаю подобные вещи, чтобы поддерживать свои кэшированные активы в актуальном состоянии, поэтому я был там:)

...