در برخی از سناریوها، سرویسکار ممکن است نیاز داشته باشد که به طور فعال با هر یک از برگههای فعالی که کنترل میکند ارتباط برقرار کند تا از یک رویداد خاص مطلع شود. مثالها عبارتند از:
- هنگامی که نسخه جدیدی از سرویسکار نصب شده است، به صفحه اطلاع میدهد تا صفحه دکمه «بهروزرسانی برای تازهسازی» را به کاربر نشان دهد تا فوراً به عملکرد جدید دسترسی پیدا کند.
- با نشان دادن علامتی مانند: "برنامه اکنون برای کار آفلاین آماده است" یا "نسخه جدید محتوای موجود" ، به کاربر اطلاع دهید که تغییری در دادههای حافظه پنهان که در سمت کارمند سرویس رخ داده است.
ما این نوع موارد استفاده را که در آن سرویسدهنده نیازی به دریافت پیامی از صفحه برای شروع ارتباط ندارد ، «بهروزرسانیهای پخش» مینامیم. در این راهنما روشهای مختلف پیادهسازی این نوع ارتباط بین صفحات و کارکنان خدمات را با استفاده از APIهای استاندارد مرورگر و کتابخانه Workbox مرور میکنیم.
موارد تولید
Tinder
Tinder PWA workbox-window
برای گوش دادن به لحظات مهم چرخه عمر کارگر خدمات از صفحه ("نصب شده"، "کنترل شده" و "فعال شده") استفاده می کند. به این ترتیب وقتی یک سرویسکار جدید وارد بازی میشود، یک بنر «بهروزرسانی موجود» را نشان میدهد تا بتواند PWA را تازهسازی کرده و به آخرین ویژگیها دسترسی داشته باشد:
اسکووش
در Squoosh PWA ، هنگامی که سرویسکار تمام داراییهای لازم برای کار آفلاین را در حافظه پنهان ذخیره میکند، پیامی به صفحه ارسال میکند تا نان تست "آماده برای کار آفلاین" را نشان دهد و کاربر را از ویژگی مطلع میکند:
با استفاده از Workbox
به رویدادهای چرخه عمر کارگر خدمات گوش دهید
workbox-window
یک رابط ساده برای گوش دادن به رویدادهای مهم چرخه عمر کارگر خدمات ارائه می دهد. این کتابخانه از APIهای سمت کلاینت مانند updatefound
و statechange استفاده میکند و شنوندگان رویدادهای سطح بالاتری را در شی workbox-window
ارائه میکند، که مصرف این رویدادها را برای کاربر آسانتر میکند.
کد صفحه زیر به شما امکان می دهد هر بار که نسخه جدیدی از Service Worker نصب می شود شناسایی کنید، بنابراین می توانید آن را به کاربر اطلاع دهید:
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', (event) => {
if (event.isUpdate) {
// Show "Update App" banner
}
});
wb.register();
صفحه را از تغییرات داده های کش مطلع کنید
بسته Workbox workbox-broadcast-update
یک روش استاندارد برای اطلاع رسانی به مشتریان پنجره در مورد به روز رسانی پاسخ ذخیره شده در حافظه پنهان ارائه می دهد. این معمولاً همراه با استراتژی StaleWhileRevalidate استفاده می شود.
برای پخش بهروزرسانیها، یک broadcastUpdate.BroadcastUpdatePlugin
به گزینههای استراتژی خود در سمت کارگر اضافه کنید:
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(),
],
})
);
در برنامه وب خود، می توانید به این رویدادها گوش دهید:
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();
}
});
استفاده از API های مرورگر
اگر عملکردی که Workbox ارائه میکند برای نیازهای شما کافی نیست، از APIهای مرورگر زیر برای اجرای «بهروزرسانیهای پخش» استفاده کنید:
Broadcast Channel API
سرویس دهنده یک شی BroadcastChannel ایجاد می کند و شروع به ارسال پیام به آن می کند. هر زمینه (به عنوان مثال صفحه) علاقه مند به دریافت این پیام ها می تواند یک شی BroadcastChannel
را نمونه سازی کند و یک کنترل کننده پیام را برای دریافت پیام ها پیاده سازی کند.
برای اطلاع رسانی به صفحه هنگام نصب سرویس کار جدید، از کد زیر استفاده کنید:
// 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'});
});
این صفحه با عضویت در 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.
}
};
این یک تکنیک ساده است، اما محدودیت آن پشتیبانی از مرورگر است: در لحظه نوشتن این مقاله، Safari از این API پشتیبانی نمیکند .
Client API
Client API با تکرار روی آرایه ای از اشیاء Client
راه ساده ای برای برقراری ارتباط با چندین مشتری از سرویس کارمند ارائه می دهد.
از کد سرویس کارگر زیر برای ارسال پیام به آخرین برگه متمرکز استفاده کنید:
// 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'});
}
});
این صفحه یک کنترل کننده پیام را برای رهگیری این پیام ها پیاده سازی می کند:
// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
// Process response
}
};
Client API یک گزینه عالی برای مواردی مانند پخش اطلاعات به چندین تب فعال است. API توسط همه مرورگرهای اصلی پشتیبانی می شود، اما همه روش های آن پشتیبانی نمی شوند. قبل از استفاده از آن، پشتیبانی مرورگر را بررسی کنید.
کانال پیام
کانال پیام به یک مرحله پیکربندی اولیه نیاز دارد، با ارسال یک پورت از صفحه به سرویس دهنده، تا یک کانال ارتباطی بین آنها ایجاد شود. صفحه یک شی MessageChannel
را نمونهسازی میکند و یک پورت را از طریق رابط postMessage()
به سرویسکار ارسال میکند:
const messageChannel = new MessageChannel();
// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
messageChannel.port2,
]);
صفحه با پیاده سازی یک کنترل کننده "onmessage" در آن پورت به پیام ها گوش می دهد:
// Listen to messages
messageChannel.port1.onmessage = (event) => {
// Process message
};
سرویسکار پورت را دریافت میکند و مرجعی را به آن ذخیره میکند:
// Initialize
let communicationPort;
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PORT_INITIALIZATION') {
communicationPort = event.ports[0];
}
});
از آن نقطه می تواند با فراخوانی postMessage()
در مرجع پورت، پیام هایی را به صفحه ارسال کند:
// Communicate
communicationPort.postMessage({type: 'MSG_ID' });
به دلیل نیاز به مقداردهی اولیه پورت ها، ممکن است MessageChannel
برای پیاده سازی پیچیده تر باشد، اما توسط همه مرورگرهای اصلی پشتیبانی می شود.
مراحل بعدی
در این راهنما، ما یک مورد خاص از ارتباطات کارگر سرویس پنجره را بررسی کردیم: "به روز رسانی پخش" . نمونههای بررسیشده شامل گوش دادن به رویدادهای مهم چرخه عمر کارکنان خدمات، و برقراری ارتباط با صفحه در مورد تغییرات در محتوا یا دادههای ذخیرهشده است. می توانید موارد استفاده جالب تری را در نظر بگیرید که در آن سرویس دهنده به طور فعال با صفحه ارتباط برقرار می کند، بدون اینکه قبلاً هیچ پیامی دریافت کند.
برای الگوهای بیشتر ارتباطات پنجره و سرویس کار، بررسی کنید:
- راهنمای ذخیره سازی ضروری : فراخوانی یک سرویس دهنده از صفحه برای ذخیره منابع از قبل (به عنوان مثال در سناریوهای واکشی اولیه).
- ارتباط دو طرفه : تفویض یک کار به یک کارگر خدماتی (مثلاً یک بارگیری سنگین)، و اطلاع رسانی صفحه از پیشرفت.