sinkronisasi-latar belakang-workbox

Saat Anda mengirim data ke server web, terkadang permintaan akan gagal. Ini mungkin karena pengguna telah kehilangan konektivitas, atau mungkin karena server mati; dalam kedua kasus tersebut, Anda sering ingin mencoba mengirim permintaan lagi nanti.

BackgroundSync API baru adalah solusi ideal untuk masalah ini. Ketika pekerja layanan mendeteksi bahwa permintaan jaringan gagal, jaringan dapat mendaftar untuk menerima peristiwa sync, yang dikirimkan ketika browser berpikir bahwa konektivitas telah kembali. Perhatikan bahwa peristiwa sinkronisasi dapat ditayangkan meskipun pengguna telah meninggalkan aplikasi, sehingga jauh lebih efektif daripada metode tradisional mencoba lagi permintaan yang gagal.

Workbox Latar Belakang Sinkronisasi dirancang untuk mempermudah penggunaan BackgroundSync API dan mengintegrasikan penggunaannya dengan modul Workbox lainnya. Ini juga menerapkan strategi penggantian untuk browser yang belum menerapkan BackgroundSync.

Browser yang mendukung BackgroundSync API akan gagal memutar ulang secara otomatis permintaan atas nama Anda di interval yang dikelola oleh browser, kemungkinan menggunakan backoff eksponensial di antara upaya replay. Di browser yang tidak mendukung BackgroundSync API secara native, Workbox Background Sync akan secara otomatis mencoba replay setiap kali pekerja layanan dimulai.

Penggunaan Dasar

Cara termudah untuk menggunakan Sinkronisasi Latar Belakang adalah menggunakan Plugin yang akan Mengantrekan permintaan yang gagal secara otomatis dan mencobanya kembali saat sync mendatang peristiwa diaktifkan.

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'
);

BackgroundSyncPlugin hook ke dalam callback plugin fetchDidFail, dan fetchDidFail hanya dipanggil jika ada pengecualian yang ditampilkan, kemungkinan besar karena hingga kegagalan jaringan. Artinya, permintaan tidak akan dicoba ulang jika ada yang diterima dengan Status error 4xx atau 5xx. Jika Anda ingin mencoba lagi semua permintaan yang menghasilkan, misalnya, status 5xx, Anda dapat melakukannya dengan menambahkan plugin fetchDidSucceed dalam strategi Anda:

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.

Penggunaan Lanjutan

Workbox Background Sync juga menyediakan class Queue, yang dapat Anda membuat instance dan menambahkan permintaan yang gagal. Permintaan yang gagal akan disimpan di IndexedDB dan dicoba lagi saat browser merasa konektivitas telah dipulihkan (yaitu saat diterima peristiwa sinkronisasi).

Membuat Antrean

Untuk membuat Workbox Background Sync Queue, Anda perlu membuatnya dengan nama antrean (yang harus unik untuk origin):

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

const queue = new Queue('myQueueName');

Nama antrean digunakan sebagai bagian dari nama tag yang mendapat Edisi register() oleh model SyncManager. Penting juga digunakan sebagai Nama Object Store untuk database tensorflow.

Menambahkan permintaan ke Antrean

Setelah membuat instance Antrean, Anda dapat menambahkan permintaan yang gagal ke instance tersebut. Anda menambahkan permintaan yang gagal dengan memanggil metode .pushRequest(). Misalnya, kode berikut menangkap setiap permintaan yang gagal dan menambahkannya ke antrean:

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());
});

Setelah ditambahkan ke antrean, permintaan akan dicoba ulang secara otomatis ketika pekerja layanan menerima peristiwa sync (yang terjadi saat browser berpikir bahwa konektivitas telah pulih). Browser yang tidak mendukung BackgroundSync API akan mencoba lagi antrean setiap kali pekerja layanan dimulai. Ini mengharuskan halaman yang mengontrol pekerja layanan untuk berjalan, sehingga sistem itu tidak akan terlalu efektif.

Menguji Sinkronisasi Latar Belakang Kotak Kerja

Sayangnya, pengujian BackgroundSync agak tidak intuitif dan sulit karena sejumlah alasan.

Pendekatan terbaik untuk menguji penerapan Anda adalah melakukan hal berikut:

  1. Memuat halaman dan mendaftarkan pekerja layanan Anda.
  2. Nonaktifkan jaringan komputer atau server web Anda.
    • JANGAN GUNAKAN DEVTOOLS CHROME SECARA OFFLINE. Kotak centang offline di DevTools hanya memengaruhi permintaan dari halaman. Permintaan Service Worker akan terus dibahas.
  3. Membuat permintaan jaringan yang harus diantrekan dengan Workbox Background Sync.
    • Anda dapat memeriksa permintaan yang telah masuk dalam antrean dengan melihat Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
  4. Sekarang aktifkan jaringan atau server web Anda.
  5. Paksa peristiwa sync awal dengan membuka Chrome DevTools > Application > Service Workers, dengan memasukkan nama tag workbox-background-sync:<your queue name> dengan <your queue name> yang seharusnya nama antrean yang Anda tetapkan, lalu klik tombol tombol.

    Contoh tombol Sinkronisasi di Chrome DevTools

  6. Anda akan melihat permintaan jaringan untuk permintaan yang gagal dan data IndexedDB kini seharusnya kosong karena permintaan telah berhasil di-replay.

Jenis

BackgroundSyncPlugin

Class yang menerapkan callback siklus proses fetchDidFail. Hal ini membuatnya penambahan permintaan yang gagal ke Antrean sinkronisasi latar belakang menjadi lebih mudah.

Properti

Queue

Class untuk mengelola penyimpanan permintaan yang gagal di IndexedDB dan mencoba lagi nanti. Semua bagian dari proses penyimpanan dan pemutaran ulang dapat diamati melalui callback.

Properti

  • konstruktor

    void

    Membuat instance Antrean dengan opsi yang diberikan

    Fungsi constructor akan terlihat seperti ini:

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

    • nama

      string

      Nama unik untuk antrean ini. Nama ini harus unik karena digunakan untuk mendaftarkan peristiwa sinkronisasi dan menyimpan permintaan di IndexedDB khusus untuk instance ini. Pesan {i>error<i} akan ditampilkan jika nama duplikat terdeteksi.

    • opsi

      QueueOptions opsional

  • nama

    string

  • getAll

    void

    Menampilkan semua entri yang belum habis masa berlakunya (per maxRetentionTime). Entri yang kedaluwarsa akan dihapus dari antrean.

    Fungsi getAll akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;QueueEntry[]&gt;

  • popRequest

    void

    Menghapus dan mengembalikan permintaan terakhir dalam antrean (beserta permintaan stempel waktu dan metadata). Objek yang ditampilkan mengambil bentuk: {request, timestamp, metadata}.

    Fungsi popRequest akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;QueueEntry&gt;

  • pushRequest

    void

    Menyimpan permintaan yang diteruskan di IndexedDB (dengan stempel waktu dan setiap metadata) di akhir antrean.

    Fungsi pushRequest akan terlihat seperti ini:

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

    • entri

      QueueEntry

    • akan menampilkan

      Janji<void>

  • registerSync

    void

    Mendaftarkan peristiwa sinkronisasi dengan tag unik untuk instance ini.

    Fungsi registerSync akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Janji<void>

  • replayRequests

    void

    Melakukan loop setiap permintaan dalam antrean dan mencoba untuk mengambilnya kembali. Jika ada permintaan yang gagal diambil ulang, permintaan tersebut ditempatkan kembali ke posisi yang sama di antrean (yang mendaftarkan percobaan ulang untuk peristiwa sinkronisasi berikutnya).

    Fungsi replayRequests akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Janji<void>

  • shiftRequest

    void

    Menghapus dan mengembalikan permintaan pertama dalam antrean (bersama dengan stempel waktu dan metadata). Objek yang ditampilkan mengambil bentuk: {request, timestamp, metadata}.

    Fungsi shiftRequest akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;QueueEntry&gt;

  • ukuran

    void

    Menampilkan jumlah entri yang ada dalam antrean. Perhatikan bahwa entri yang masa berlakunya habis (per maxRetentionTime) juga disertakan dalam jumlah ini.

    Fungsi size akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;number&gt;

  • unshiftRequest

    void

    Menyimpan permintaan yang diteruskan di IndexedDB (dengan stempel waktu dan setiap metadata) di awal antrean.

    Fungsi unshiftRequest akan terlihat seperti ini:

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

    • entri

      QueueEntry

    • akan menampilkan

      Janji<void>

QueueOptions

Properti

  • forceSyncFallback

    boolean opsional

  • maxRetentionTime

    angka opsional

  • onSync

    OnSyncCallback opsional

QueueStore

Class untuk mengelola penyimpanan permintaan dari Queue di IndexedDB, diindeks oleh nama antrean mereka untuk memudahkan akses.

Sebagian besar developer tidak perlu mengakses class ini secara langsung; untuk kasus penggunaan lanjutan.

Properti

  • konstruktor

    void

    Mengaitkan instance ini dengan instance Queue, sehingga entri yang ditambahkan dapat yang diidentifikasi berdasarkan nama antrean mereka.

    Fungsi constructor akan terlihat seperti ini:

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

    • queueName

      string

  • deleteEntry

    void

    Menghapus entri untuk ID yang diberikan.

    PERINGATAN: metode ini tidak memastikan entri yang dihapus adalah milik antrean (yaitu, cocok dengan queueName). Namun, batasan ini bisa diterima karena class ini tidak diekspos secara publik. Pemeriksaan tambahan akan membuat metode ini lebih lambat dari yang seharusnya.

    Fungsi deleteEntry akan terlihat seperti ini:

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

    • id

      angka

    • akan menampilkan

      Janji<void>

  • getAll

    void

    Menampilkan semua entri di toko yang cocok dengan queueName.

    Fungsi getAll akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;QueueStoreEntry[]&gt;

  • popEntry

    void

    Menghapus dan menampilkan entri terakhir dalam antrean yang cocok dengan queueName.

    Fungsi popEntry akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;QueueStoreEntry&gt;

  • pushEntry

    void

    Tambahkan entri terakhir dalam antrean.

    Fungsi pushEntry akan terlihat seperti ini:

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

    • entri

      UnidentifiedQueueStoreEntry

    • akan menampilkan

      Janji<void>

  • shiftEntry

    void

    Menghapus dan menampilkan entri pertama dalam antrean yang cocok dengan queueName.

    Fungsi shiftEntry akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;QueueStoreEntry&gt;

  • ukuran

    void

    Menampilkan jumlah entri di toko yang cocok dengan queueName.

    Fungsi size akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Promise&lt;number&gt;

  • unshiftEntry

    void

    Tambahkan entri terlebih dahulu dalam antrean.

    Fungsi unshiftEntry akan terlihat seperti ini:

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

    • entri

      UnidentifiedQueueStoreEntry

    • akan menampilkan

      Janji<void>

StorableRequest

Class untuk mempermudah serialisasi dan de-serialisasi permintaan sehingga dapat disimpan di Responden.

Sebagian besar developer tidak perlu mengakses class ini secara langsung; untuk kasus penggunaan lanjutan.

Properti

  • konstruktor

    void

    Menerima objek data permintaan yang dapat digunakan untuk membuat Request tetapi juga dapat disimpan di IndexedDB.

    Fungsi constructor akan terlihat seperti ini:

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

    • requestData

      RequestData

      Objek data permintaan yang menyertakan url ditambah properti apa pun yang relevan dari [requestInit]https://fetch.spec.whatwg.org/#requestinit.

  • clone

    void

    Membuat dan menampilkan clone mendalam dari instance.

    Fungsi clone akan terlihat seperti ini:

    () => {...}

  • toObject

    void

    Menampilkan clone mendalam dari objek _requestData instance.

    Fungsi toObject akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      RequestData

  • toRequest

    void

    Mengonversi instance ini ke Permintaan.

    Fungsi toRequest akan terlihat seperti ini:

    () => {...}

    • akan menampilkan

      Permintaan

  • fromRequest

    void

    Mengonversi objek Request menjadi objek biasa yang dapat terstruktur di-clone atau di-string oleh JSON.

    Fungsi fromRequest akan terlihat seperti ini:

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

    • minta

      Permintaan