【问题标题】:Notify new application version with browser service workers使用浏览器服务人员通知新的应用程序版本
【发布时间】:2016-11-30 18:02:05
【问题描述】:

我使用 Polymer 和 polymer-cli 以及生成良好的 service-worker 用于缓存和离线构建了一个 html/js 应用程序(一个渐进式 Web 应用程序)。

我想知道当有新版本的应用程序可用时如何通知用户并邀请他重新启动浏览器。

有什么想法吗?

编辑

在 IO2016 的一次演讲中,Eric Bidel 谈到了 service worker 并通知用户应用程序的新版本: https://youtu.be/__KvYxcIIm8?list=PLOU2XLYxmsILe6_eGvDN3GyiodoV3qNSC&t=1510

需要查看google IO Web源码

【问题讨论】:

  • 网络应用支持push-notifications。但这在通知用户应用程序已更新时似乎是错误的。为什么要用户“重新启动浏览器”? Service Worker 会在检测到任何更改时自动执行此操作...
  • 我看到并理解的是服务工作者不会重新启动应用程序,它只是在缓存下载完成后更新自身和缓存,您必须重新启动应用程序才能获取新应用程序在缓存中...我只记得 Eric Bidel 在 IO 的一次演讲中谈到了这个,我会试着找到这个演讲。

标签: polymer service-worker progressive-web-apps


【解决方案1】:

参考资料:

  • https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
  • https://classroom.udacity.com/courses/ud899

    // page script
    document.addEventListener('DOMContentLoaded', function(){
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker
            .register('/sw.js')
            .then(function(registration) {
                console.info('ServiceWorker registration successful with scope:', registration.scope);
    
               // if there's no controller, this page wasn't loaded
               // via a service worker, so they're looking at the latest version.
               // In that case, exit early
               if (!navigator.serviceWorker.controller) return;
    
               // if there's an updated worker already waiting, update
               if (registration.waiting) {
                   console.info('show toast and upon click update...');
                   registration.waiting.postMessage({ updateSw: true });
                   return;
               }
    
               // if there's an updated worker installing, track its
               // progress. If it becomes "installed", update
               if (registration.installing) {
                   registration.addEventListener('statechange', function(){
                       if (registration.installing.state == 'installed'){
                           console.info('show toast and upon click update...');
                           registration.installing.postMessage({ updateSw: true });
                           return;          
                       }
                   });
               }
    
               // otherwise, listen for new installing workers arriving.
               // If one arrives, track its progress.
               // If it becomes "installed", update
               registration.addEventListener('updatefound', function(){
                   let newServiceWorker = registration.installing;
    
                   newServiceWorker.addEventListener('statechange', function() {
                       if (newServiceWorker.state == 'installed') {
                           console.info('show toast and upon click update...');
                           newServiceWorker.postMessage({ updateSw: true });           
                       }
                   });
               });
            })
            .catch(function(error) {
                console.info('ServiceWorker registration failed:', error);
            });
    
    
          navigator.serviceWorker.addEventListener('controllerchange', function() {
              window.location.reload();
          });
        }
    
    });
    
    // sw script
    self.addEventListener('message', function(e) {
        if (e.data.updateSw){
            self.skipWaiting();
        }
    });
    

【讨论】:

    【解决方案2】:

    感谢 IO 团队 .. 我们需要检查当前 service-worker 是否变得多余

    // Check to see if the service worker controlling the page at initial load
    // has become redundant, since this implies there's a new service worker with fresh content.
    if (navigator.serviceWorker && navigator.serviceWorker.controller) {
       navigator.serviceWorker.controller.onstatechange = function(event) {
         if (event.target.state === 'redundant') {
           // Define a handler that will be used for the next io-toast tap, at which point it
           // be automatically removed.
           const tapHandler = function() {
             window.location.reload();
           };
    
           if (IOWA.Elements && IOWA.Elements.Toast &&
              IOWA.Elements.Toast.showMessage) {
                IOWA.Elements.Toast.showMessage(
                'A new version of this app is available.', tapHandler, 'Refresh',
                null, 0); // duration 0 indications shows the toast indefinitely.
           } else {
             tapHandler(); // Force reload if user never was shown the toast.
           }
         }
      };
    }
    

    【讨论】:

    • 我认为这不再是必要的,因为polymer-cli 在构建时生成服务工作者,我很确定这种代码被包括在内。至于引用 IOWA 应用程序...首选模板应用程序是 shop app,它包含 redundant 状态检查。
    • 我认为商店应用程序不包含冗余检查,因为这不是想要的行为。大多数时候 service-worker 用于缓存和离线:这是 polymer-cli 构建离线和缓存工作者的原因。但是,如果您关心您的用户使用您的应用程序的最新版本,您需要处理它。如果浏览器在缓存更新后重新加载,用户体验会很差。
    猜你喜欢
    • 2014-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    相关资源
    最近更新 更多