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".
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:
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:
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ư
updatefound
và thay đổ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:
- Hướng dẫn lưu vào bộ nhớ đệm ngầm định: Gọi một trình chạy dịch vụ từ trang đến bộ nhớ đệm trước (ví dụ: trong các trường hợp tìm nạp trước).
- Giao tiếp hai chiều: Uỷ quyền công việc cho một nhân viên dịch vụ (ví dụ: tải xuống rất nhiều) và thông báo tiến trình trên trang.