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

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

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

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

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

Tinder

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

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

سكووش

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

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

استخدام Workbox

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

توفّر workbox-window واجهة واضحة للاستماع إلى الأحداث المهمة لمراحل نشاط موظفي الخدمات. تستخدم المكتبة واجهات برمجة التطبيقات من جهة العميل، مثل updatefound وstatechange، وتوفّر أدوات معالجة أحداث ذات مستوى أعلى في عنصر 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 طريقة عادية لإعلام عملاء النوافذ بأنّه تم تعديل استجابة مخزَّنة مؤقتًا. ويشيع استخدام هذا الإجراء مع استراتيجية StaleAlias Re مؤهَّلة

لبث التعديلات، أضِف 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 تكفي لاحتياجاتك، يمكنك استخدام واجهات برمجة تطبيقات المتصفّح التالية لتنفيذ "broadcast update" (تحديثات البث):

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

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

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

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

للاطّلاع على مزيد من أنماط التواصل بين عاملَي التشغيل وWindows في الخدمة، يُرجى الاطّلاع على ما يلي:

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

مراجع إضافية