简体   繁体   English

工作箱-后台同步-离线发布-重播浏览器重新联机时的事件

[英]Workbox - Background Sync - Offline Post - Replay Events when the browser is back online doesn't get triggered

I am using workbox v4.3.1 to provide offline capability to the users of the web application. 我正在使用Workbox v4.3.1向Web应用程序的用户提供脱机功能。

While everything works perfectly in Chrome as you would expect a PWA to work (ie everything is cached locally, all the updates from the APP are captured in IndexedDB and synced back to the server when the application is back online. 虽然所有功能都可以在Chrome中正常运行,就像您希望PWA可以正常工作一样(即,所有内容都在本地缓存,但来自应用程序的所有更新都捕获在IndexedDB中,并在应用程序重新联机时同步回服务器。

However the major use case for me is to provide support for iOS Safari and as a PWA. 但是,对我而言,主要用例是为iOS Safari和PWA提供支持。

While all the pages are cached locally using the Service Worker in Safari and all the offline updates are also captured in the indexed DB as shown below, 尽管所有页面都使用Safari中的Service Worker在本地缓存,并且所有脱机更新也都捕获在索引数据库中,如下所示,

在此处输入图片说明

However, when the connection returns online, the sync event is not triggered by the browser (Safari in this case). 但是,当连接返回联机状态时,同步事件不会由浏览器(在这种情况下为Safari)触发。 While background sync is not supported natively by Safari, I would expect that when I refresh the page, SW initialisation should trigger the sync event manually if it finds some data to be refreshed to the server in the indexed DB. 尽管Safari本身不支持后台同步,但我希望刷新页面时,如果SW初始化在索引数据库中发现一些要刷新到服务器的数据,则应该手动触发sync事件。

But this is not happening and I tried to manually listen for the "message" - "replayRequests" and then replay the requests - that did not work as well. 但这没有发生,我尝试手动监听“消息”-“ replayRequests”,然后重播请求-效果不佳。

Any help here would be appreciated. 在这里的任何帮助,将不胜感激。 Here is the service worker code for reference. 这是服务人员代码供参考。

// If we're not in the context of a Web Worker, then don't do anything
if ("function" === typeof importScripts) {
  importScripts(
    "https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"
  );

  //Plugins
  // Background Sync Plugin.
  const bgSyncPlugin = new workbox.backgroundSync.Plugin("offlineSyncQueue", {
    maxRetentionTime: 24 * 60
  });

  // Alternate method for creating a queue and managing the events ourselves.
  const queue = new workbox.backgroundSync.Queue("offlineSyncQueue");
  workbox.routing.registerRoute(
    matchCb,
    workbox.strategies.networkOnly({
      plugins: [
        {
          fetchDidFail: async ({ request }) => {
            await queue.addRequest(request);
          }
        }
      ]
    }),
    "POST"
  );
  // CacheKeyControlPlugin
  const myCacheKeyPlugin = {
    cacheKeyWillBeUsed: async ({ request, mode }) => {
      normalizedUrl = removeTimeParam(request.url);
      return new Request(normalizedUrl);
    }
  };

  if (workbox) {
    console.info("SW - Workbox is available and successfully installed");
  } else {
    console.info("SW - Workbox unavailable");
  }

  //Intercept all api requests
  var matchCb = ({ url, event }) => {
    // Filter out the presence api calls
    return url.pathname.indexOf("somethingidontwanttocache") == -1;
  };

  function removeTimeParam(urlString) {
    let url = new URL(urlString);
    url.searchParams.delete("time");
    return url.toString();
  }
  /* //Pre cache a page and see if it works offline - Temp code
  workbox.precaching.precache(getPageAPIRequestURLs(), {
    cleanUrls: false
  }); */
  workbox.routing.registerRoute(
    matchCb,
    new workbox.strategies.CacheFirst({
      cacheName: "application-cache",
      plugins: [myCacheKeyPlugin]
    })
  );

  self.addEventListener("message", event => {
    if (event.data === "replayRequests") {
      queue.replayRequests();
    }
  });
}

workbox-background-sync emulates background sync functionality in browsers that lack native support by replaying queued requests whenever the service worker process starts up . 每当服务工作者进程启动时, workbox-background-sync都会通过重播排队的请求来模拟缺少本机支持的浏览器中的后台同步功能。 The service worker process is meant to be lightweight and short lived, and is killed aggressively when there's a period of time without any events, and then is started up again in response to further events. 服务工作者进程本来应该是轻量级的,并且生命周期短,并且在一段时间内没有任何事件时会被猛烈杀死,然后响应于其他事件而再次启动。

Reloading a web page may cause the service worker process to start up, assuming it had previously been stopped. 重新加载网页可能会导致Service Worker进程启动,前提是该进程先前已停止。 But if the service worker is still running, then reloading the page will just cause a fetch event to be fired on the existing process. 但是,如果服务工作者仍在运行,则重新加载页面只会导致在现有进程上触发fetch事件。

The interval at which a service worker process can remain idle before it's killed is browser-dependent. 服务工作者进程在被杀死之前可以保持空闲的时间间隔取决于浏览器。

Chrome's DevTools offers a method of inspecting the state of a service worker and starting/stopping it on demand, but I don't believe Safari's DevTools offers that functionality. Chrome的DevTools提供了一种检查服务人员状态并按需启动/停止状态的方法,但是我不认为Safari的DevTools提供了该功能。 If you wanted to guanratee that a service worker was stopped and then start it up again, I would quit Safari, reopen it, and then navigate back to your web app. 如果您想证明服务工作者已停止然后再启动,请退出Safari,重新打开它,然后导航回您的Web应用程序。

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

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