sinkronisasi-latar belakang-workbox

Saat Anda mengirimkan data ke server web, terkadang permintaan akan gagal. Hal ini mungkin karena pengguna telah kehilangan konektivitas, atau mungkin karena server sedang tidak aktif. Dalam kedua kasus tersebut, Anda sering kali ingin mencoba mengirim permintaan lagi nanti.

BackgroundSync API baru adalah solusi ideal untuk masalah ini. Jika mendeteksi bahwa permintaan jaringan gagal, pekerja layanan dapat mendaftar untuk menerima peristiwa sync, yang akan dikirim saat browser menganggap konektivitas telah kembali. Perhatikan bahwa peristiwa sinkronisasi dapat ditayangkan meskipun pengguna telah keluar dari aplikasi, sehingga jauh lebih efektif daripada metode tradisional untuk mencoba lagi permintaan yang gagal.

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

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

Penggunaan Dasar

Cara termudah untuk menggunakan Sinkronisasi Latar Belakang adalah dengan menggunakan Plugin yang akan secara otomatis Mengantrekan permintaan yang gagal dan mencoba lagi saat peristiwa sync berikutnya 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 disebabkan kegagalan jaringan. Artinya, permintaan tidak akan dicoba lagi jika ada respons 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 ke 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

Sinkronisasi Latar Belakang Workbox juga menyediakan class Queue, yang dapat Anda buat instance dan tambahkan permintaan yang gagal. Permintaan yang gagal akan disimpan di IndexedDB dan dicoba lagi saat browser menganggap konektivitas telah dipulihkan (yaitu saat menerima peristiwa sinkronisasi).

Membuat Antrean

Untuk membuat Antrean Sinkronisasi Latar Belakang Workbox, Anda harus membuatnya dengan nama antrean (yang harus unik untuk origin Anda):

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

const queue = new Queue('myQueueName');

Nama antrean digunakan sebagai bagian dari nama tag yang di-register() oleh SyncManager global. Nama ini juga digunakan sebagai nama Object Store untuk database IndexedDB.

Menambahkan permintaan ke Antrean

Setelah membuat instance Antrean, Anda dapat menambahkan permintaan yang gagal ke instance tersebut. Tambahkan 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 otomatis dicoba lagi ketika pekerja layanan menerima peristiwa sync (yang terjadi ketika browser menganggap konektivitas telah dipulihkan). Browser yang tidak mendukung BackgroundSync API akan mencoba kembali antrean setiap kali pekerja layanan dimulai. Hal ini mengharuskan halaman yang mengontrol pekerja layanan berjalan, sehingga tidak akan cukup efektif.

Menguji Sinkronisasi Latar Belakang Workbox

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

Pendekatan terbaik untuk menguji penerapan Anda adalah dengan melakukan hal berikut:

  1. Muat sebuah halaman dan daftarkan pekerja layanan Anda.
  2. Nonaktifkan jaringan komputer atau nonaktifkan server web.
    • JANGAN GUNAKAN CHROME DEVTOOLS SECARA Offline. Kotak centang offline di DevTools hanya memengaruhi permintaan dari halaman. Permintaan Service Worker akan terus diproses.
  3. Membuat permintaan jaringan yang harus diantrekan dengan Sinkronisasi Latar Belakang Workbox.
    • Anda dapat memeriksa apakah permintaan telah dimasukkan ke dalam antrean dengan melihat di 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, masukkan nama tag workbox-background-sync:<your queue name> dengan <your queue name> sebagai nama antrean yang Anda tetapkan, lalu klik tombol 'Sinkronkan'.

    Contoh tombol Sinkronisasi di Chrome DevTools

  6. Anda akan melihat permintaan jaringan untuk permintaan yang gagal dan data IndexedDB kini akan kosong karena permintaan telah berhasil diputar ulang.

Jenis

BackgroundSyncPlugin

Class yang menerapkan callback siklus proses fetchDidFail. Hal ini mempermudah penambahan permintaan yang gagal ke Antrean sinkronisasi latar belakang.

Properti

Queue

Class untuk mengelola penyimpanan permintaan yang gagal di IndexedDB dan mencobanya 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 terlihat seperti:

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

    • name

      string

      Nama unik untuk antrean ini. Nama ini harus unik karena digunakan untuk mendaftarkan peristiwa sinkronisasi dan permintaan penyimpanan di IndexedDB khusus untuk instance ini. Pesan error akan ditampilkan jika nama duplikat terdeteksi.

    • opsi

      QueueOptions opsional

  • name

    string

  • getAll

    void

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

    Fungsi getAll terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<QueueEntry[]>

  • popRequest

    void

    Menghapus dan menampilkan permintaan terakhir dalam antrean (beserta stempel waktu dan metadatanya). Objek yang ditampilkan berbentuk: {request, timestamp, metadata}.

    Fungsi popRequest terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<QueueEntry>

  • pushRequest

    void

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

    Fungsi pushRequest terlihat seperti:

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

    • entri

      QueueEntry

    • akan menampilkan

      Promise<void>

  • registerSync

    void

    Mendaftarkan peristiwa sinkronisasi dengan tag unik untuk instance ini.

    Fungsi registerSync terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<void>

  • replayRequests

    void

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

    Fungsi replayRequests terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<void>

  • shiftRequest

    void

    Menghapus dan menampilkan permintaan pertama dalam antrean (beserta stempel waktu dan metadatanya). Objek yang ditampilkan berbentuk: {request, timestamp, metadata}.

    Fungsi shiftRequest terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<QueueEntry>

  • ukuran

    void

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

    Fungsi size terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<number>

  • unshiftRequest

    void

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

    Fungsi unshiftRequest terlihat seperti:

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

    • entri

      QueueEntry

    • akan menampilkan

      Promise<void>

QueueOptions

Properti

  • forceSyncFallback

    boolean opsional

  • maxRetentionTime

    nomor opsional

  • onSync

    OnSyncCallback opsional

QueueStore

Class untuk mengelola penyimpanan permintaan dari Queue di IndexedDB, yang diindeks berdasarkan nama antreannya untuk akses yang lebih mudah.

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

Properti

  • konstruktor

    void

    Mengaitkan instance ini dengan instance Antrean, sehingga entri yang ditambahkan dapat diidentifikasi berdasarkan nama antreannya.

    Fungsi constructor terlihat seperti:

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

    • queueName

      string

  • deleteEntry

    void

    Menghapus entri untuk ID yang diberikan.

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

    Fungsi deleteEntry terlihat seperti:

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

    • id

      angka

    • akan menampilkan

      Promise<void>

  • getAll

    void

    Menampilkan semua entri di toko yang cocok dengan queueName.

    Fungsi getAll terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<QueueStoreEntry[]>

  • popEntry

    void

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

    Fungsi popEntry terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<QueueStoreEntry>

  • pushEntry

    void

    Menambahkan entri terakhir dalam antrean.

    Fungsi pushEntry terlihat seperti:

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

    • entri

      UnidentifiedQueueStoreEntry

    • akan menampilkan

      Promise<void>

  • shiftEntry

    void

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

    Fungsi shiftEntry terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<QueueStoreEntry>

  • ukuran

    void

    Menampilkan jumlah entri di toko yang cocok dengan queueName.

    Fungsi size terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Promise<number>

  • unshiftEntry

    void

    Tambahkan entri terlebih dahulu dalam antrean.

    Fungsi unshiftEntry terlihat seperti:

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

    • entri

      UnidentifiedQueueStoreEntry

    • akan menampilkan

      Promise<void>

StorableRequest

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

Sebagian besar developer tidak perlu mengakses class ini secara langsung karena class ini diekspos 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 terlihat seperti:

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

    • requestData

      RequestData

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

  • clone

    void

    Membuat dan menampilkan clone instance yang mendalam.

    Fungsi clone terlihat seperti:

    ()=> {...}

  • toObject

    void

    Menampilkan clone mendalam objek _requestData instance.

    Fungsi toObject terlihat seperti:

    ()=> {...}

    • akan menampilkan

      RequestData

  • toRequest

    void

    Mengonversi instance ini menjadi Permintaan.

    Fungsi toRequest terlihat seperti:

    ()=> {...}

    • akan menampilkan

      Permintaan

  • fromRequest

    void

    Mengonversi objek Request menjadi objek biasa yang dapat di-clone secara terstruktur atau distring JSON.

    Fungsi fromRequest terlihat seperti:

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

    • minta

      Permintaan