Menyiarkan pembaruan ke halaman dengan pekerja layanan

Andrew Guan
Andrew Guan
Demián Renzulli
Demián Renzulli

Dalam beberapa skenario, pekerja layanan mungkin perlu berkomunikasi secara proaktif dengan tab yang dikontrolnya untuk menginformasikan peristiwa tertentu. Contohnya mencakup:

  • Memberi tahu halaman ketika versi baru pekerja layanan telah diinstal, sehingga halaman dapat menampilkan tombol "Update untuk memuat ulang" kepada pengguna untuk mengakses fungsi baru segera.
  • Memberi tahu pengguna tentang perubahan pada data {i>cache<i} yang terjadi di sisi pekerja layanan, dengan menunjukkan indikasi, seperti: "Aplikasi sekarang siap untuk bekerja secara offline", atau "Versi baru aplikasi konten tersedia".
Diagram yang menampilkan pekerja layanan berkomunikasi dengan halaman untuk mengirim update.

Kita akan menyebut jenis kasus penggunaan ini di mana pekerja layanan tidak perlu menerima pesan dari halaman untuk memulai komunikasi "update siaran". Dalam panduan ini, kita akan meninjau berbagai cara implementasi jenis komunikasi antara laman dan pekerja layanan, dengan menggunakan API browser, dan library Workbox.

Kasus produksi

Tinder

PWA Tinder menggunakan workbox-window untuk memproses momen siklus proses pekerja layanan yang penting dari halaman ("installed", "controlled", dan "diaktifkan"). Dengan begitu, saat pekerja layanan baru digunakan, status "Update Tersedia" akan ditampilkan banner standar, agar pengguna dapat memuat ulang PWA dan mengakses fitur terbaru:

Screenshot aplikasi web Tinder &#39;Update Tersedia&#39; fungsionalitasnya.
Di PWA Tinder, pekerja layanan memberi tahu halaman bahwa versi baru sudah siap, dan halaman akan menampilkan "Update Tersedia" kepada pengguna banner standar.

Skuosh

Di Squoosh PWA, saat pekerja layanan telah meng-cache semua informasi yang diperlukan aset agar berfungsi secara offline, sistem ini akan mengirimkan pesan ke halaman untuk menampilkan pesan "Siap digunakan secara offline" toast, yang memberi tahu pengguna tentang fitur:

Screenshot aplikasi web Squoosh &#39;Siap untuk bekerja secara offline&#39; fungsionalitasnya.
Di PWA Squoosh, pekerja layanan menyiarkan update ke halaman saat cache siap, dan halaman menampilkan "Siap untuk bekerja secara offline" toast.

Menggunakan Workbox

Memproses peristiwa siklus proses pekerja layanan

workbox-window menyediakan antarmuka yang mudah untuk memproses siklus proses pekerja layanan yang penting peristiwa. Pada prinsipnya, library ini menggunakan API sisi klien seperti updatefound dan statechange dan menyediakan pemroses peristiwa level lebih tinggi di objek workbox-window, sehingga memudahkan untuk memakai peristiwa ini.

Kode halaman berikut memungkinkan Anda mendeteksi setiap kali versi baru pekerja layanan diinstal, sehingga Anda dapat menyampaikannya kepada pengguna:

const wb = new Workbox('/sw.js');

wb.addEventListener('installed', (event) => {
  if (event.isUpdate) {
    // Show "Update App" banner
  }
});

wb.register();

Memberi tahu halaman tentang perubahan data cache

Paket Workbox workbox-broadcast-update menyediakan cara standar untuk memberi tahu klien jendela bahwa respons yang di-cache telah diperbarui. Ini adalah paling umum digunakan bersama dengan instance StaleWhileRevalidate strategi.

Untuk menyiarkan info terbaru, tambahkan broadcastUpdate.BroadcastUpdatePlugin ke opsi strategi Anda di sisi pekerja layanan:

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';

registerRoute(
  ({url}) => url.pathname.startsWith('/api/'),
  new StaleWhileRevalidate({
    plugins: [
      new BroadcastUpdatePlugin(),
    ],
  })
);

Di aplikasi web, Anda dapat memproses peristiwa berikut seperti:

navigator.serviceWorker.addEventListener('message', async (event) => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.data.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedUrl} = event.data.payload;

    // Do something with cacheName and updatedUrl.
    // For example, get the cached content and update
    // the content on the page.
    const cache = await caches.open(cacheName);
    const updatedResponse = await cache.match(updatedUrl);
    const updatedText = await updatedResponse.text();
  }
});

Menggunakan API browser

Jika fungsi yang disediakan Workbox tidak cukup untuk kebutuhan Anda, gunakan browser berikut API untuk menerapkan "update siaran":

Broadcast Channel API

Pekerja layanan membuat saluran BroadcastChannel objek dan mulai mengirimkan pesan untuknya. Konteks apa pun (mis. halaman) yang tertarik untuk menerima pesan ini dapat membuat instance BroadcastChannel dan menerapkan pengendali pesan untuk menerima pesan.

Untuk memberi tahu halaman saat pekerja layanan baru diinstal, gunakan kode berikut:

// Create Broadcast Channel to send messages to the page
const broadcast = new BroadcastChannel('sw-update-channel');

self.addEventListener('install', function (event) {
  // Inform the page every time a new service worker is installed
  broadcast.postMessage({type: 'CRITICAL_SW_UPDATE'});
});

Halaman memproses peristiwa ini dengan berlangganan sw-update-channel:

// Create Broadcast Channel and listen to messages sent to it
const broadcast = new BroadcastChannel('sw-update-channel');

broadcast.onmessage = (event) => {
  if (event.data && event.data.type === 'CRITICAL_SW_UPDATE') {
    // Show "update to refresh" banner to the user.
  }
};

Ini adalah teknik sederhana, tetapi keterbatasannya adalah dukungan browser: pada saat penulisan ini, Safari tidak mendukung API ini.

Client API

Client API menyediakan konfigurasi yang mudah cara berkomunikasi dengan beberapa klien dari pekerja layanan dengan melakukan iterasi melalui berbagai Objek Client.

Gunakan kode pekerja layanan berikut untuk mengirim pesan ke tab yang terakhir difokuskan:

// Obtain an array of Window client objects
self.clients.matchAll(options).then(function (clients) {
  if (clients && clients.length) {
    // Respond to last focused tab
    clients[0].postMessage({type: 'MSG_ID'});
  }
});

Halaman ini menerapkan pengendali pesan untuk menangkap pesan tersebut:

// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
     if (event.data && event.data.type === 'MSG_ID') {
         // Process response
   }
};

Client API adalah opsi yang tepat untuk kasus seperti menyiarkan informasi ke beberapa tab aktif. Tujuan API didukung oleh semua browser utama, tetapi tidak semua metodenya mendukungnya. Periksa dukungan browser sebelum menggunakannya.

Saluran Pesan

Saluran Pesan memerlukan langkah konfigurasi awal, dengan meneruskan porta dari halaman ke pekerja layanan, untuk membuat saluran komunikasi di antara mereka. Halaman membuat instance objek MessageChannel dan meneruskan port ke pekerja layanan, melalui antarmuka postMessage():

const messageChannel = new MessageChannel();

// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
  messageChannel.port2,
]);

Halaman memproses pesan dengan menerapkan "onmessage" pada porta tersebut:

// Listen to messages
messageChannel.port1.onmessage = (event) => {
  // Process message
};

Pekerja layanan menerima port dan menyimpan referensi ke port tersebut:

// Initialize
let communicationPort;

self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'PORT_INITIALIZATION') {
    communicationPort = event.ports[0];
  }
});

Sejak saat itu, aplikasi dapat mengirim pesan ke halaman, dengan memanggil postMessage() dalam referensi ke porta:

// Communicate
communicationPort.postMessage({type: 'MSG_ID' });

MessageChannel mungkin lebih kompleks untuk diimplementasikan karena perlunya menginisialisasi port, didukung oleh semua browser besar.

Langkah berikutnya

Dalam panduan ini, kita telah mempelajari satu kasus tertentu komunikasi pekerja layanan antara Windows: "update siaran". Contoh yang dieksplorasi mencakup mendengarkan pekerja layanan yang penting peristiwa siklus proses, dan berkomunikasi ke halaman tentang perubahan konten atau data yang di-cache. Anda dapat memikirkan kasus penggunaan yang lebih menarik di mana pekerja layanan secara proaktif berkomunikasi dengan laman, tanpa menerima pesan apa pun sebelumnya.

Untuk pola komunikasi Window dan service worker lainnya, lihat:

  • Panduan penyimpanan dalam cache penting: Memanggil pekerja layanan dari halaman untuk sumber daya cache di awal (misalnya dalam skenario pengambilan data).
  • Komunikasi dua arah: Mendelegasikan tugas kepada pekerja layanan (mis. download yang berat), dan memberi tahu halaman tentang kemajuannya.

Referensi lainnya