작업 상자 백그라운드 동기화

웹 서버로 데이터를 보낼 때 요청이 실패하는 경우가 있습니다. 그것은 사용자의 연결이 끊어졌거나 서버가 다운되면 어떤 경우든 요청을 전송하여 나중에 다시 실행할 수 있습니다.

새로운 BackgroundSync API 이 문제에 대한 이상적인 솔루션입니다. 서비스 워커가 네트워크 요청이 실패하면 sync 이벤트를 수신하도록 등록할 수 있습니다. 브라우저에서 연결이 재개되었다고 생각하면 전송됩니다. 사용자가 동기화를 중단한 후에도 동기화 이벤트가 전달될 수 훨씬 더 효과적이므로 실패한 요청 재시도

Workbox 백그라운드 동기화는 BackgroundSync API에 추가하고 이 API의 사용을 다른 Workbox 모듈과 통합합니다. 그것은 또한 아직 구현 기능이 구현되지 않은 브라우저를 위한 대체 전략을 BackgroundSync의 도움을 받을 수 있습니다.

BackgroundSync API를 지원하는 브라우저에서 자동으로 재생할 수 없습니다. 사용자를 대신하여 브라우저에서 관리하는 간격입니다. 재생 시도 사이에 지수 백오프를 사용할 가능성이 높습니다. 브라우저에 기본적으로 BackgroundSync API를 지원하지 않는 경우 Workbox Background Sync에서 서비스 워커가 시작될 때마다 자동으로 재생을 시도합니다.

기본 사용법

백그라운드 동기화를 사용하는 가장 쉬운 방법은 Plugin 실패한 요청을 자동으로 큐에 추가하고 향후 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],
  }),
  'POST'
);

BackgroundSyncPluginfetchDidFail 플러그인 콜백 fetchDidFail는 예외가 발생한 경우에만 호출됩니다. 지양합니다 즉, 요청이 있을 경우 요청이 재시도되지 않습니다. 수신된 응답을 4xx 또는 5xx 오류 상태. 5xx 등의 결과로 이어지는 모든 요청을 재시도하려면 방법은 fetchDidSucceed 플러그인 추가 전략을 세울 수 있습니다.

const statusPlugin = {
  fetchDidSucceed: ({response}) => {
    if (response.status >= 500) {
      // Throwing anything here will trigger fetchDidFail.
      throw new Error('Server error.');
    }
    // If it's not 5xx, use the response as-is.
    return response;
  },
};

// Add statusPlugin to the plugins array in your strategy.

고급 사용

Workbox 백그라운드 동기화는 Queue 클래스도 제공합니다. 이 클래스는 실패한 요청을 인스턴스화하고 추가할 수 있습니다 실패한 요청은 (IndexedDB) 브라우저에서 연결이 복원되었다고 판단될 때 재시도됩니다 (즉, 가 동기화 이벤트를 수신할 때).

큐 만들기

Workbox 백그라운드 동기화 대기열을 생성하려면 대기열 이름 (고유한 이름이어야 함) origin의 구성원입니다.

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

const queue = new Queue('myQueueName');

대기열 이름은 register()간 전 세계 SyncManager 그것은 또한 객체 저장소 이름: IndexedDB 데이터베이스를 생성합니다.

큐에 요청 추가

큐 인스턴스를 만들고 나면 실패한 요청을 인스턴스에 추가할 수 있습니다. .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 백그라운드 동기화 테스트

안타깝게도 BackgroundSync 테스트는 다소 직관적이지 않고 어렵습니다. 여러 가지 이유로 인해

구현을 테스트하는 가장 좋은 방법은 다음을 실행하는 것입니다.

  1. 페이지를 로드하고 서비스 워커를 등록합니다.
  2. 컴퓨터의 네트워크를 끄거나 웹 서버를 끕니다.
    • Chrome DevTools를 오프라인에서 사용하지 마세요. 오프라인 체크박스를 선택하면 DevTools는 페이지의 요청에만 영향을 미칩니다. 서비스 워커 요청 진행될 것입니다
  3. Workbox 백그라운드 동기화를 사용하여 대기열에 추가해야 하는 네트워크 요청을 실행합니다.
    • 요청이 큐에 추가되었는지 확인하려면 Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
  4. 이제 네트워크 또는 웹 서버를 켭니다.
  5. 다음으로 이동하여 조기 sync 이벤트를 강제 실행합니다. Chrome DevTools > Application > Service Workers: workbox-background-sync:<your queue name>, 여기서 <your queue name>는 다음과 같아야 함 클릭한 다음 '동기화' 버튼을 클릭합니다.

    Chrome DevTools의 동기화 버튼 예

  6. 실패한 요청에 대해 네트워크 요청이 처리되고 요청이 변경되었기 때문에 이제 IndexedDB 데이터가 비어 있어야 합니다. 성공적으로 다시 재생되었습니다.

유형

BackgroundSyncPlugin

fetchDidFail 수명 주기 콜백을 구현하는 클래스입니다. 이렇게 하면 실패한 요청을 백그라운드 동기화 큐에 더 쉽게 추가할 수 있습니다.

속성

Queue

실패한 요청을 IndexedDB에 저장하고 재시도하는 것을 관리하는 클래스 확인할 수 있습니다 저장 및 재생 프로세스의 모든 부분은 있습니다.

속성

  • 생성자

    void

    특정 옵션으로 Queue의 인스턴스를 만듭니다.

    constructor 함수는 다음과 같습니다.

    (name: string, options?: QueueOptions) => {...}

    • 이름

      문자열

      이 큐의 고유한 이름입니다. 이름은 동기화 이벤트를 등록하고 요청을 저장하는 데 사용되므로 고유합니다. IndexedDB에 저장됩니다. 다음과 같은 경우 오류가 발생합니다. 중복 이름이 감지되는 경우

    • 옵션

      QueueOptions 선택사항

  • 이름

    문자열

  • getAll

    void

    maxRetentionTime당 만료되지 않은 모든 항목을 반환합니다. 만료된 항목은 대기열에서 삭제됩니다.

    getAll 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;QueueEntry[]&gt;

  • popRequest

    void

    대기열에서 마지막 요청을 삭제하고 반환합니다( 타임스탬프 및 모든 메타데이터) 반환된 객체의 형식은 다음과 같습니다. {request, timestamp, metadata}

    popRequest 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;QueueEntry&gt;

  • pushRequest

    void

    전달된 요청을 IndexedDB에 저장합니다 (타임스탬프 및 메타데이터)를 추가할 수 있습니다.

    pushRequest 함수는 다음과 같습니다.

    (entry: QueueEntry) => {...}

    • entry

      QueueEntry

    • returns

      프로미스<void>

  • registerSync

    void

    이 인스턴스에 고유한 태그를 사용하여 동기화 이벤트를 등록합니다.

    registerSync 함수는 다음과 같습니다.

    () => {...}

    • returns

      프로미스<void>

  • replayRequests

    void

    큐의 각 요청을 반복하고 다시 가져오기를 시도합니다. 요청을 다시 가져오지 못하면 큐 (다음 동기화 이벤트에 대한 재시도를 등록함)

    replayRequests 함수는 다음과 같습니다.

    () => {...}

    • returns

      프로미스<void>

  • shiftRequest

    void

    대기열에서 첫 번째 요청을 삭제하고 반환합니다( 타임스탬프 및 모든 메타데이터) 반환된 객체의 형식은 다음과 같습니다. {request, timestamp, metadata}

    shiftRequest 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;QueueEntry&gt;

  • 크기

    void

    큐에 있는 항목 수를 반환합니다. 만료된 항목 (maxRetentionTime당)도 이 수에 포함됩니다.

    size 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;number&gt;

  • unshiftRequest

    void

    전달된 요청을 IndexedDB에 저장합니다 (타임스탬프 및 메타데이터)입니다.

    unshiftRequest 함수는 다음과 같습니다.

    (entry: QueueEntry) => {...}

    • entry

      QueueEntry

    • returns

      프로미스<void>

QueueOptions

속성

  • forceSyncFallback

    불리언 선택사항

  • maxRetentionTime

    숫자 선택사항

  • onSync

    OnSyncCallback 선택사항

QueueStore

IndexedDB에서 큐의 요청을 저장하는 것을 관리하는 클래스입니다. 쉽게 액세스할 수 있도록 큐 이름으로 색인이 생성됩니다.

대부분의 개발자는 이 클래스에 직접 액세스할 필요가 없습니다. 고급 사용 사례에 노출되어 있습니다

속성

  • 생성자

    void

    추가된 항목이 식별됩니다

    constructor 함수는 다음과 같습니다.

    (queueName: string) => {...}

    • queueName

      문자열

  • deleteEntry

    void

    지정된 ID의 항목을 삭제합니다.

    경고: 이 방법을 사용해도 삭제된 항목이 큐에서 호출되어야 합니다 (즉, queueName와 일치). 그러나 이러한 제한은 이 클래스는 공개적으로 노출되지 않기 때문입니다. 추가로 확인하면 이 방법은 필요한 것보다 느립니다.

    deleteEntry 함수는 다음과 같습니다.

    (id: number) => {...}

    • id

      숫자

    • returns

      프로미스<void>

  • getAll

    void

    queueName과 일치하는 스토어의 모든 항목을 반환합니다.

    getAll 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;QueueStoreEntry[]&gt;

  • popEntry

    void

    큐에서 queueName와 일치하는 마지막 항목을 삭제하고 반환합니다.

    popEntry 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;QueueStoreEntry&gt;

  • pushEntry

    void

    큐의 마지막에 항목을 추가합니다.

    pushEntry 함수는 다음과 같습니다.

    (entry: UnidentifiedQueueStoreEntry) => {...}

    • entry

      UnidentifiedQueueStoreEntry

    • returns

      프로미스<void>

  • shiftEntry

    void

    큐에서 queueName와 일치하는 첫 번째 항목을 삭제하고 반환합니다.

    shiftEntry 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;QueueStoreEntry&gt;

  • 크기

    void

    queueName와 일치하는 스토어의 항목 수를 반환합니다.

    size 함수는 다음과 같습니다.

    () => {...}

    • returns

      Promise&lt;number&gt;

  • unshiftEntry

    void

    큐에서 먼저 항목을 앞에 추가합니다.

    unshiftEntry 함수는 다음과 같습니다.

    (entry: UnidentifiedQueueStoreEntry) => {...}

    • entry

      UnidentifiedQueueStoreEntry

    • returns

      프로미스<void>

StorableRequest

요청을 더 쉽게 직렬화 및 역직렬화할 수 있도록 하여 IndexedDB에 저장할 수 있습니다.

대부분의 개발자는 이 클래스에 직접 액세스할 필요가 없습니다. 고급 사용 사례에 노출되어 있습니다

속성

  • 생성자

    void

    요청을 구성하는 데 사용할 수 있는 요청 데이터의 객체를 받습니다. Request이지만 IndexedDB에 저장할 수도 있습니다.

    constructor 함수는 다음과 같습니다.

    (requestData: RequestData) => {...}

    • requestData

      RequestData

      다음을 포함하는 요청 데이터의 객체입니다. url 및 관련 속성 [requestInit]https://fetch.spec.whatwg.org/#requestinit

  • clone

    void

    인스턴스의 딥 클론을 만들고 반환합니다.

    clone 함수는 다음과 같습니다.

    () => {...}

  • toObject

    void

    인스턴스 _requestData 객체의 딥 클론을 반환합니다.

    toObject 함수는 다음과 같습니다.

    () => {...}

    • returns

      RequestData

  • toRequest

    void

    이 인스턴스를 요청으로 변환합니다.

    toRequest 함수는 다음과 같습니다.

    () => {...}

    • returns

      요청

  • fromRequest

    void

    Request 객체를 구조화될 수 있는 일반 객체로 변환합니다. JSON으로 문자열로 변환할 수 있습니다

    fromRequest 함수는 다음과 같습니다.

    (request: Request) => {...}

    • 요청

      요청