다시 온라인 상태가 되면 요청 재시도

웹 서버를 요청할 때 오류가 발생할 가능성이 있습니다. 사용자의 연결이 끊어졌거나 원격 서버가 다운되었기 때문일 수 있습니다.

이 문서에서는 주로 서비스 워커에서 GET 요청을 처리하는 데 중점을 두었지만 POST, PUT 또는 DELETE와 같은 다른 메서드를 사용할 수도 있습니다. 이러한 메서드는 웹 앱에 데이터를 제공하기 위해 백엔드 API와 통신하는 데 자주 사용됩니다. 서비스 워커가 없을 때 이러한 요청이 실패하면 다시 온라인 상태가 되었을 때 사용자가 수동으로 재시도해야 하며, 사용자가 항상 기억할 수 있는 작업이 아닙니다.

이것이 애플리케이션에 해당하는 경우, 그리고 서비스 워커가 혼합되어 있는 경우, 사용자가 다시 온라인 상태가 되었을 때 실패한 요청 전송을 재시도하는 것이 이상적입니다. BackgroundSync API는 이 문제의 해결책을 제공합니다. 서비스 워커는 실패한 네트워크 요청을 감지하면 브라우저에서 연결이 반환되었음을 감지할 때 sync 이벤트를 수신하도록 등록할 수 있습니다. sync 이벤트는 사용자가 이벤트를 등록한 페이지에서 벗어나더라도 전달될 수 있으므로, 실패한 요청을 재시도하는 다른 방법보다 더 효과적입니다.

Workbox는 workbox-background-sync 모듈을 사용하여 이 API를 추상화하므로 BackgroundSync API를 다른 Workbox 모듈과 더 쉽게 사용할 수 있습니다. 또한 아직 BackgroundSync를 지원하지 않는 브라우저를 위한 대체 전략도 구현합니다.

기본 사용법

BackgroundSyncPluginworkbox-background-sync 모듈에서 내보내지며 실패한 요청을 큐에 추가하고 향후 sync 이벤트가 실행될 때 다시 시도하는 데 사용할 수 있습니다.

import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
  maxRetentionTime: 24 * 60 // Retry for max of 24 Hours (specified in minutes)
});

registerRoute(
  /\/api\/.*\/*.json/,
  new NetworkOnly({
    plugins: [bgSyncPlugin]
  }),
  // An optional third parameter specifies the request method
  'POST'
);

여기서 BackgroundSyncPlugin는 JSON 데이터를 가져오는 API 경로에 대한 POST 요청과 일치하는 경로에 적용됩니다. 사용자가 오프라인 상태인 경우 사용자가 다시 온라인 상태가 되면 BackgroundSyncPlugin에서 요청을 재시도하지만 최대 하루 동안만 가능합니다.

고급 사용법

workbox-background-sync는 실패한 요청을 인스턴스화하고 추가할 수 있는 Queue 클래스도 제공합니다. BackgroundSyncPlugin의 경우와 마찬가지로, 실패한 요청은 IndexedDB에 저장되고 브라우저에서 연결이 복원되었다고 판단하면 시도됩니다.

큐 만들기

큐를 만들려면 큐 이름을 나타내는 문자열로 Queue 객체를 인스턴스화합니다.

import {Queue} from 'workbox-background-sync';

const queue = new Queue('myQueueName');

큐 이름은 전역 SyncManager에서 제공하는 register() 메서드에서 생성된 태그 이름의 일부로 사용됩니다. 또한 IndexedDB 데이터베이스에서 제공하는 객체 저장소에 사용되는 이름이기도 합니다.

큐에 요청 추가

Queue 인스턴스를 만든 후 pushRequest() 메서드를 사용하여 실패한 요청을 추가할 수 있습니다.

import {Queue} from 'workbox-background-sync';

const queue = new Queue('myQueueName');

self.addEventListener('fetch', (event) => {
  // Add in your own criteria here to return early if this
  // isn't a request that should use background sync.
  if (event.request.method !== 'POST') {
    return;
  }

  const bgSyncLogic = async () => {
    try {
      const response = await fetch(event.request.clone());
      return response;
    } catch (error) {
      await queue.pushRequest({request: event.request});
      return error;
    }
  };

  event.respondWith(bgSyncLogic());
});

큐에 추가되면 서비스 워커가 sync 이벤트를 수신하면 요청이 자동으로 재시도됩니다. 브라우저에서 네트워크를 다시 사용할 수 있다고 판단하기 때문입니다. BackgroundSync API를 지원하지 않는 브라우저는 서비스 워커가 시작될 때마다 요청을 재시도합니다. 이는 실패한 요청을 재시도하는 덜 효과적인 방법이지만 일종의 대체 방안입니다.

workbox-background-sync 테스트 중

백그라운드 동기화 동작 테스트는 까다로울 수 있지만 Chrome DevTools에서 수행할 수 있습니다. 현재 최상의 접근 방식은 다음과 같습니다.

  1. 서비스 워커를 등록하는 페이지를 로드합니다.
  2. 컴퓨터의 네트워크 연결을 끄거나 웹 서버의 전원을 끕니다. Chrome DevTools에서 오프라인 전환 기능을 사용하지 마세요. 오프라인 체크박스는 페이지의 요청에만 영향을 미치지만, 서비스 워커 요청은 계속 진행됩니다.
  3. workbox-background-sync로 큐에 추가해야 하는 네트워크 요청을 실행합니다. Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests를 살펴보면 큐에 추가된 요청을 확인할 수 있습니다.
  4. 이제 네트워크 연결을 복원하거나 웹 서버를 다시 켜세요.
  5. Chrome DevTools > Application > Service Workers로 이동하여 초기 sync 이벤트를 강제 적용합니다. workbox-background-sync:<your queue name>의 태그 이름을 입력합니다. 여기서 <your queue name>은 설정한 큐의 이름입니다.
  6. '동기화' 버튼을 클릭합니다.
    Chrome DevTools의 애플리케이션 패널에 있는 백그라운드 동기화 유틸리티의 스크린샷 동기화 이벤트가 &#39;workbox-background-sync&#39; 모듈의 &#39;myQueueName&#39; 대기열에 지정됩니다.
  7. 이제 이전에 실패한 네트워크 요청이 재시도되고 통과된 것을 확인할 수 있습니다. 결과적으로 요청이 성공적으로 재생되었으므로 IndexedDB 저장소는 비어 있어야 합니다.

결론

workbox-background-sync를 사용하여 실패한 네트워크 요청을 재시도하면 사용자가 실패한 API 요청을 다시 제출하도록 허용하여 API로 전송하려는 데이터가 손실되지 않도록 하는 등 앱의 사용자 환경과 안정성을 개선할 수 있습니다. 분석과 같은 자체 데이터의 간극을 메우는 데도 사용할 수 있습니다. 실제로 workbox-google-analytics 모듈은 내부적으로 workbox-background-sync를 사용하여 Google 애널리틱스로 데이터를 전송하기 위해 실패한 요청을 재시도합니다.

사용 사례가 무엇이든 workbox-background-sync은 이러한 종류의 작업을 간소화하여 개발자 환경을 개선하고 웹 애플리케이션의 사용자 환경과 기능을 개선할 더 많은 기회를 제공합니다.