简体   繁体   English

Service Worker 更新事件触发器

[英]Service worker update event trigger

Following this link https://github.com/deanhume/pwa-update-available , I am trying to implement the service worker update, but I am facing issues like the event update is not getting triggered, which I think is related to my app design, which basically a SPA, means I am always on index.html,which behaves like app-shell and I am pushing the contents in the contents area, depending upon which button is clicked.按照此链接https://github.com/deanhume/pwa-update-available ,我正在尝试实现服务工作者更新,但我遇到了诸如事件更新未触发之类的问题,我认为这与我的应用程序设计,基本上是一个 SPA,意味着我总是在 index.html,它的行为类似于 app-shell,我正在推送内容区域中的内容,具体取决于单击哪个按钮。

only other page is login/index.html只有其他页面是登录/索引。html

the contents for app.js to install/update service worker is like this: app.js 安装/更新 service worker 的内容是这样的:

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;
            });
          }  

and sw.js file contents are like this:和 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 partial-contents of index.html: index.html 的部分内容:

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

so basically the issue I am facing is, triggering the update, when I am changing the version number like v28 to v29 and reload the page, I am getting the prompt, but I am not getting the prompt even when I logout, login or exit and reopen the app.所以基本上我面临的问题是,触发更新,当我将版本号(如 v28 更改为 v29 并重新加载页面时)我收到提示,但即使我注销、登录或退出时也没有收到提示并重新打开应用程序。

How I can fix this?我该如何解决这个问题?

Note:PWA is my progressive app folder, I am using php/yii2 as backend and not using node server or other JS framework.注意:PWA 是我的渐进式应用程序文件夹,我使用 php/yii2 作为后端,而不是使用节点服务器或其他 JS 框架。

the service worker registration routine you have only triggers when you index.html is loaded in the browser.仅当您在浏览器中加载 index.html 时才会触发服务工作者注册例程。 It is the only time that code is executed.这是代码执行的唯一时间。

Unless you periodically poll your server or possibly open a websocket (sort of expensive just for this) you wont know if a new service worker is available.除非您定期轮询您的服务器或可能打开 websocket(为此有点贵),否则您不会知道是否有新的 service worker 可用。 You could have the user register for push notifications....too much headache for this.你可以让用户注册推送通知……这太让人头疼了。

So pool the server every few hours or days for an update.因此,每隔几个小时或几天将服务器汇集一次以进行更新。

If there is an update you can trigger an update routine.如果有更新,您可以触发更新例程。

I would put the polling logic in the actual service worker code to keep it off the UI, if you are a SPA you are already locking the UI thread enough LOL.我会将轮询逻辑放在实际的服务工作者代码中以使其远离 UI,如果您是 SPA,那么您已经足够锁定 UI 线程了。

There are lots of ways to skin this cat, setTimeout(..., {lots of seconds}), when the service worker wakes from being dormant, etc.有很多方法可以给这只猫剥皮,setTimeout(..., {lots of seconds}),当服务工作者从休眠中醒来时等等。

If you can make a HEAD request that would keep the network traffic to a minimum.如果您可以发出 HEAD 请求,将网络流量保持在最低限度。

If there is an update you could then post a message to the UI to update the service worker.如果有更新,您可以向 UI 发布消息以更新 service worker。

This is not what I would call trivial code.这不是我所说的琐碎代码。 I do similar stuff to keep my cached assets up to date, so I have been there:)我做了类似的事情来保持我的缓存资产是最新的,所以我一直在那里:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM