بث التحديثات على الصفحات التي تتضمن مشغّلي الخدمات

في بعض السيناريوهات، قد يحتاج عامل الخدمة إلى التواصل بشكل استباقي مع أي من الموظفين التي تتحكم بها للإبلاغ بحدث معين. تشمل الأمثلة ما يلي:

  • إبلاغ الصفحة عند تثبيت إصدار جديد من مشغّل الخدمات، بحيث يمكن عرض زر "تحديث لإعادة التحميل" للمستخدم للوصول إلى الوظائف الجديدة فورًا.
  • إعلام المستخدم بأي تغيير في البيانات المخزنة مؤقتًا حدث من جانب عامل الخدمة، عن طريق تعرض مؤشرًا، مثل: "التطبيق جاهز الآن للعمل بلا اتصال بالإنترنت" أو "الإصدار الجديد من المحتوى المتوفر".
مخطّط بياني يعرض عامل خدمة يتواصل مع الصفحة لإرسال تحديث

سنتصل بأنواع حالات الاستخدام هذه عندما لا يحتاج عامل الخدمة إلى تلقّي رسالة من الصفحة لبدء رسالة "بث تحديثات". في هذا الدليل، سنراجع وطرق تنفيذ هذا النوع من الاتصال بين الصفحات وعاملي الخدمات، باستخدام طرق واجهات برمجة التطبيقات للمتصفح ومكتبة Workbox.

حالات الإنتاج

تيندر

يستخدم تطبيق Tinder PWA workbox-window للاستماع إلى أهم لحظات دورة حياة عامل الخدمة من الصفحة ("مثبت" و"متحكم" "نشط"). بهذه الطريقة، عندما يتم تشغيل مشغّل خدمات جديد، تظهر الرسالة "تحديث متاح". بانر، ليتمكّنوا من إعادة تحميل تطبيق الويب التقدّمي (PWA) والوصول إلى أحدث الميزات:

لقطة شاشة لتطبيق الويب "يتوفّر تحديث" على تطبيق Tinder الأخرى.
في تطبيق الويب التقدّمي Tinder، يُبلِغ مشغّل الخدمات الصفحة بأنّ إصدارًا جديدًا جاهز، وتعرض الصفحة للمستخدمين رسالة "التحديث متاح". بانر

قرع

في تطبيق الويب التقدّمي Squoosh، عندما يخزِّن مشغّل الخدمات مؤقتًا جميع البيانات مواد العرض لجعلها تعمل بلا اتصال بالإنترنت، يتم إرسال رسالة إلى الصفحة لعرض الرسالة "جاهز للعمل بلا اتصال بالإنترنت" لكي يعرف المستخدم عن الميزة:

لقطة شاشة لتطبيق الويب Squoosh "جاهز للعمل بلا اتصال بالإنترنت" الأخرى.
في تطبيق الويب التقدّمي Squoosh، يُبث عامل الخدمة تحديثًا للصفحة عندما تكون ذاكرة التخزين المؤقت جاهزة، وتعرض الصفحة "جاهز للعمل بلا اتصال بالإنترنت". نخب

استخدام Workbox

الاستماع إلى أحداث مراحل نشاط عاملي الخدمة

توفّر workbox-window واجهة واضحة للاستماع إلى مراحل نشاط مشغّل الخدمات المهمة الأحداث. بشكل غير مرئي، تستخدم المكتبة واجهات برمجة تطبيقات من جانب العميل مثل updatefound وتغيير الولاية وتوفِّر أدوات معالجة أحداث ذات مستوى أعلى في كائن workbox-window، ما يسهِّل على الاستفادة من هذه الأحداث.

يتيح لك رمز الصفحة التالي اكتشاف كل مرة يتم فيها تثبيت إصدار جديد من مشغّل الخدمات، حتى تتمكّن من إبلاغ المستخدم بها:

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

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

wb.register();

إبلاغ صفحة التغييرات في بيانات ذاكرة التخزين المؤقت

حزمة Workbox workbox-broadcast-update توفّر طريقة عادية لإشعار عملاء الفترة الزمنية بأنه تم تعديل الاستجابة المخزَّنة مؤقتًا. هذا هو الأكثر استخدامًا مع العمود Stale whileRe للتعرّف على الاستراتيجية.

لبث آخر الأخبار، أضِف 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();
  }
});

استخدام واجهات برمجة التطبيقات للمتصفّح

إذا لم تكن الوظائف التي توفّرها Workbox كافية لتلبية احتياجاتك، استخدِم المتصفّح التالي واجهات برمجة التطبيقات اللازمة لتنفيذ "تحديثات البث":

واجهة برمجة تطبيقات قناة البث

ينشئ عامل الخدمة 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 مع واجهة برمجة التطبيقات هذه.

واجهة برمجة تطبيقات العميل

توفّر 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
   }
};

تُعد واجهة برمجة تطبيقات العميل خيارًا رائعًا لحالات مثل بث المعلومات إلى علامات تبويب نشطة متعددة. تشير رسالة الأشكال البيانية تتوافق واجهة برمجة التطبيقات مع جميع المتصفحات الرئيسية، ولكن ليست كل طرقها متوافقة. يُرجى مراجعة توافق المتصفّح قبل استخدامه.

قناة الرسائل

تتطلب قناة المراسلة خطوة الضبط الأولية، عن طريق تمرير منفذ من الصفحة إلى عامل الخدمة، لإنشاء ووسيلة تواصل بينهما. تنشئ الصفحة مثيلاً للعنصر 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 أكثر تعقيدًا بسبب الحاجة إلى إعداد المنافذ، ولكنه متوافقة مع جميع المتصفحات الرئيسية

الخطوات التالية

تطرّقنا في هذا الدليل إلى حالة معيّنة من التواصل بين مشغّلي الخدمات والنوافذ: "تحديثات البث": تشمل الأمثلة التي تم استكشافها الاستماع إلى عامل الخدمة المهم والأحداث في مراحل النشاط، والتواصل مع الصفحة بشأن التغييرات في المحتوى أو البيانات المخزّنة مؤقتًا. يمكنك التفكير من حالات الاستخدام الأكثر إثارة للاهتمام التي يتواصل فيها عامل الخدمة بشكل استباقي مع الصفحة دون تلقي أي رسالة سابقًا.

للتعرف على المزيد من أنماط اتصال النوافذ وعاملي الخدمات، اطلع على:

  • دليل التخزين المؤقت الضمني: الاتصال بمشغّل الخدمات من الصفحة ذاكرة التخزين المؤقت مقدمًا (على سبيل المثال، في سيناريوهات الجلب المسبق).
  • التواصل المتبادل: تفويض مهمة إلى عامل خدمة (على سبيل المثال، تنزيل مكثف)، وإبقاء الصفحة على اطلاع بالتقدم.

مراجع إضافية