【问题标题】:Communicating a successful workbox-background-sync replay to open clients将成功的 workbox-background-sync 重播传达给打开的客户端
【发布时间】:2021-08-02 10:46:54
【问题描述】:

我正在使用 React 17、Workbox 5 和 react-scripts 4。 我使用 PWA 模板创建了一个反应应用程序:

npx create-react-app my-app --template cra-template-pwa

我使用 workbox-background-sync 中的 BackgroundSyncPlugin 来处理我的离线请求,因此当应用再次在线时,请求将自动发送。 问题是我不知道请求何时在我的 React 代码中发送,所以我可以更新一些状态,并向用户显示一条消息。

如何从 Service Worker 向我的 React 代码传达请求已发送并且 React 应该更新状态?

提前致谢。

【问题讨论】:

    标签: reactjs create-react-app progressive-web-apps workbox


    【解决方案1】:

    您可以在配置BackgroundSyncPlugin 时使用自定义onSync 回调来完成此操作。然后,只要满足重试请求的条件,就会执行此代码,而不是 Workbox 的 built-in replayRequests() logic。

    您可以在此回调中包含您喜欢的任何逻辑; this.shiftRequest() 和 this.unshiftRequest(entry) 可用于删除排队的请求以重试它们,然后在重试失败时重新添加它们。这是对默认 replayRequests() 的改编,当重试成功时,它将使用 postMessage() 与所有受控的 window 客户端通信。

    async function postSuccessMessage(response) {
      const clients = await self.clients.matchAll();
      for (const client of clients) {
        // Customize this message format as you see fit.
        client.postMessage({
          type: 'REPLAY_SUCCESS',
          url: response.url,
        });
      }
    }
    
    async function customReplay() {
      let entry;
      while ((entry = await this.shiftRequest())) {
        try {
          const response = await fetch(entry.request.clone());
          // Optional: check response.ok and throw if it's false if you
          // want to treat HTTP 4xx and 5xx responses as retriable errors.
    
          postSuccessMessage(response);
        } catch (error) {
          await this.unshiftRequest(entry);
    
          // Throwing an error tells the Background Sync API
          // that a retry is needed.
          throw new Error('Replaying failed.');
        }
      }
    }
    
    const bgSync = new BackgroundSyncPlugin('api-queue', {
      onSync: customReplay,
    });
    
    // Now add bgSync to a Strategy that's associated with
    // a route you want to retry:
    registerRoute(
      ({url}) => url.pathname === '/api_endpoint',
      new NetworkOnly({plugins: [bgSync]}),
      'POST'
    );
    

    在您的客户端页面中,您可以使用navigator.seviceWorker.addEventListener('message', ...) 来侦听来自服务工作者的传入消息并采取适当的措施。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 2018-10-12
      • 2014-03-07
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多