Phát thông báo cập nhật đến các trang bằng trình chạy dịch vụ

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

Trong một số trường hợp, trình chạy dịch vụ có thể cần phải chủ động giao tiếp với bất kỳ nhân viên nào đang hoạt động các thẻ mà nó kiểm soát để thông báo về một sự kiện nhất định. Ví dụ:

  • Thông báo cho trang khi phiên bản mới của trình chạy dịch vụ được cài đặt để trang có thể hiển thị nút "Cập nhật để làm mới" cho người dùng để họ truy cập vào chức năng mới ngay lập tức.
  • Thông báo cho người dùng biết về thay đổi đối với dữ liệu được lưu vào bộ nhớ đệm diễn ra ở phía trình chạy dịch vụ, bằng cách hiển thị một chỉ báo, chẳng hạn như: "Ứng dụng này hiện đã sẵn sàng hoạt động khi không có mạng" hoặc "Phiên bản mới của có sẵn".
Sơ đồ cho thấy một trình chạy dịch vụ giao tiếp với trang để gửi nội dung cập nhật.

Chúng tôi sẽ gọi những loại trường hợp sử dụng này mà trong đó trình chạy dịch vụ không cần nhận thông báo từ trên trang để bắt đầu thông báo "broadcast updates". Trong hướng dẫn này, chúng ta sẽ xem xét các cách triển khai loại hình giao tiếp này giữa trang và trình chạy dịch vụ, bằng cách sử dụng trình duyệt và thư viện Hộp công việc.

Trường hợp sản xuất

Tinder

PWA Tinder sử dụng workbox-window để nghe các thời điểm quan trọng trong vòng đời của trình chạy dịch vụ trên trang ("cài đặt", "kiểm soát" và "đã kích hoạt"). Bằng cách đó, khi một worker mới vào hoạt động, nó sẽ hiển thị thông báo "Đã có bản cập nhật" biểu ngữ để họ có thể làm mới PWA và sử dụng các tính năng mới nhất:

Ảnh chụp màn hình ứng dụng web của Tinder có thông báo "Đã có bản cập nhật" của Google.
Trong PWA Tinder, trình chạy dịch vụ sẽ cho trang biết rằng phiên bản mới đã sẵn sàng và trang sẽ hiển thị cho người dùng thông báo "Đã có bản cập nhật" biểu ngữ.

Tiếng Squoosh

Trong Squoosh PWA, khi trình chạy dịch vụ đã lưu vào bộ nhớ đệm tất cả dữ liệu cần thiết để tài sản hoạt động khi không có mạng, nó sẽ gửi thông báo đến trang để hiển thị thông báo "Sẵn sàng hoạt động khi không có mạng" thông báo ngắn để người dùng biết về tính năng này:

Ảnh chụp màn hình ứng dụng web Squoosh "Sẵn sàng hoạt động khi không có mạng" của Google.
Trong PWA Squoosh, trình chạy dịch vụ sẽ truyền thông tin cập nhật cho trang khi bộ nhớ đệm đã sẵn sàng và trang hiển thị thông báo "Sẵn sàng hoạt động khi không có mạng" thông báo ngắn.

Sử dụng Workbox

Theo dõi các sự kiện trong vòng đời của trình thực thi dịch vụ

workbox-window cung cấp một giao diện đơn giản để theo dõi vòng đời quan trọng của trình chạy dịch vụ sự kiện. Về sau, thư viện này sử dụng các API phía máy khách như updatefoundthay đổi tiểu bang và cung cấp trình nghe sự kiện cấp cao hơn trong đối tượng workbox-window, giúp thông báo người dùng sử dụng các sự kiện này.

Đoạn mã trang sau cho phép bạn phát hiện mỗi khi phiên bản mới của trình chạy dịch vụ được cài đặt, để bạn có thể thông báo cho người dùng:

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

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

wb.register();

Thông báo cho trang về những thay đổi đối với dữ liệu bộ nhớ đệm

Gói Workbox workbox-broadcast-update cung cấp một cách thức tiêu chuẩn để thông báo cho các ứng dụng khách sử dụng cửa sổ rằng phản hồi đã lưu vào bộ nhớ đệm đã được cập nhật. Đây là thường được sử dụng nhất cùng với mã SCũ Trong khiXác thực lại .

Để truyền tin cập nhật, hãy thêm broadcastUpdate.BroadcastUpdatePlugin vào các lựa chọn chiến lược của bạn trong phía trình chạy dịch vụ:

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

Trong ứng dụng web, bạn có thể theo dõi các sự kiện sau:

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

Sử dụng API trình duyệt

Nếu chức năng mà Workbox cung cấp không đủ cho nhu cầu của bạn, hãy sử dụng trình duyệt sau Các API để triển khai chức năng "broadcast updates":

API Broadcast Channel

Trình chạy dịch vụ tạo một broadcastChannel đối tượng và bắt đầu gửi gửi tin nhắn đến đó. Bất kỳ ngữ cảnh nào (ví dụ: trang) muốn nhận các thông báo này đều có thể tạo thực thể BroadcastChannel và triển khai một trình xử lý thông báo để nhận thông báo.

Để thông báo cho trang khi một trình chạy dịch vụ mới được cài đặt, hãy sử dụng mã sau:

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

Trang nghe những sự kiện này bằng cách đăng ký 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.
  }
};

Đây là một kỹ thuật đơn giản, nhưng giới hạn của kỹ thuật này là hỗ trợ trình duyệt: tại thời điểm thực hiện bài viết này, Safari không hỗ trợ API này.

API ứng dụng

API Ứng dụng cung cấp thông tin đơn giản cách giao tiếp với nhiều máy khách từ trình chạy dịch vụ bằng cách lặp lại qua một mảng Đối tượng Client.

Sử dụng mã trình chạy dịch vụ sau đây để gửi thư đến thẻ được đặt tiêu điểm gần đây nhất:

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

Trang này triển khai một trình xử lý thông báo để chặn những thông báo sau:

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

API ứng dụng là một lựa chọn tuyệt vời cho các trường hợp như truyền thông tin đến nhiều thẻ đang hoạt động. Chiến lược phát hành đĩa đơn API được hỗ trợ bởi tất cả các trình duyệt chính, nhưng không phải tất cả các phương thức đều được hỗ trợ. Kiểm tra khả năng hỗ trợ trình duyệt trước đang sử dụng nó.

Kênh tin nhắn

Cần có Kênh tin nhắn bước định cấu hình ban đầu, bằng cách truyền một cổng từ trang đến trình chạy dịch vụ để thiết lập một kênh liên lạc giữa chúng. Trang này tạo thực thể cho đối tượng MessageChannel và truyền một cổng vào trình chạy dịch vụ, thông qua giao diện postMessage():

const messageChannel = new MessageChannel();

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

Trang này nghe thông báo bằng cách triển khai thông báo "onmessage" trình xử lý trên cổng đó:

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

Service worker nhận cổng và lưu tham chiếu đến đó:

// Initialize
let communicationPort;

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

Từ thời điểm đó, ứng dụng có thể gửi thông báo tới trang bằng cách gọi postMessage() trong tệp tham chiếu đến cổng:

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

Việc triển khai MessageChannel có thể phức tạp hơn do cần phải khởi tạo cổng, nhưng được tất cả các trình duyệt chính hỗ trợ.

Các bước tiếp theo

Trong hướng dẫn này, chúng ta đã tìm hiểu một trường hợp cụ thể về giao tiếp của trình chạy dịch vụ Window to Service: "phát sóng nội dung cập nhật". Các ví dụ được khám phá bao gồm lắng nghe trình chạy dịch vụ quan trọng các sự kiện trong vòng đời và thông báo với trang về những thay đổi trong nội dung hoặc dữ liệu được lưu vào bộ nhớ đệm. Bạn có thể suy nghĩ các trường hợp sử dụng thú vị hơn trong đó worker chủ động giao tiếp với trang, mà không phải nhận bất kỳ tin nhắn nào trước đó.

Để biết thêm các mẫu giao tiếp của Window và Service worker, hãy xem:

Tài nguyên khác