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

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

이 문서에서는 주로 서비스 워커에서 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 데이터베이스에서 제공하는 Object Store에 사용되는 이름이기도 합니다.

큐에 요청 추가

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;myQueueName&#39;의 대기열에 동기화 이벤트가 지정되었습니다. &#39;workbox-background-sync&#39; 관련 모듈을 마칩니다
  7. 이제 이전에 실패한 네트워크 요청이 재시도되어 처리되는 것을 확인할 수 있습니다. 요청이 성공적으로 재생되었으므로 IndexedDB 저장소는 비어 있어야 합니다.

결론

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

사용 사례에 관계없이 workbox-background-sync를 사용하면 이러한 유형의 작업이 간소화되어 개발자 환경이 개선되고 웹 애플리케이션의 사용자 환경과 기능을 개선할 수 있는 기회가 더 많이 주어집니다.