استخدام عامل الخدمات لإدارة الإشعارات

Kate Jeffreys
Kate Jeffreys

في هذا الدرس التطبيقي حول الترميز، ستستخدم عامل خدمة لإدارة الإشعارات. تفترض التعليمات الواردة هنا أنّك على دراية بعمال الخدمات وأساسيات طلب إذن الإشعارات وإرسالها. إذا كنت بحاجة إلى مراجعة سريعة حول الإشعارات، يمكنك الاطّلاع على الدرس التطبيقي البدء في استخدام Notifications API. للاطّلاع على مزيد من المعلومات عن مشغِّلات الخدمات، يمكنك الاطّلاع على مقالة مقدّمة عن مشغِّلات الخدمات التي كتبها "مات غونت".

يتم تلقائيًا حظر الإشعارات من تطبيق Glitch المضمّن، لذا لن تتمكّن من معاينة التطبيق على هذه الصفحة. بدلاً من ذلك، إليك الخطوات التي يجب اتّباعها:

  1. انقر على Remix to Edit (إنشاء ريمكس لتعديل المحتوى) ليصبح المشروع قابلاً للتعديل.
  2. لمعاينة الموقع الإلكتروني، اضغط على عرض التطبيق. ثم اضغط على ملء الشاشة ملء الشاشة.

من المفترض أن يتم فتح Glitch في علامة تبويب جديدة في Chrome.

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

التعرّف على نموذج التطبيق والرمز المبدئي

ابدأ بالاطّلاع على التطبيق المباشر في علامة التبويب الجديدة في Chrome:

  1. اضغط على Ctrl ‏+ Shift ‏+ J (أو Command ‏+ Option ‏+ J على نظام التشغيل Mac) لفتح DevTools.
  2. انقر على علامة التبويب وحدة التحكم.

  3. تأكَّد من تحديد الخيار معلومات في القائمة المنسدلة المستويات بجانب مربّع الفلتر.

  4. في وحدة تحكّم "أدوات مطوّري البرامج في Chrome" لتطبيقك المنشور، من المفترض أن تظهر لك رسالة في وحدة التحكّم:

    TODO: Implement getRegistration().

    هذه رسالة من مقتطف دالة ستنفذها في هذا الدليل التعليمي.

لنلقِ الآن نظرة على رمز نموذج التطبيق في Glitch المضمّن في هذه الصفحة.

  1. في Glitch المضمّن، اطّلِع على public/index.js:

    • هناك أربعة نماذج بديلة للدوالّ التي ستنفّذها: registerServiceWorker وgetRegistration وunRegisterServiceWorker وsendNotification.

    • تطلب الدالة requestPermission إذن المستخدم لإرسال الإشعارات. إذا كنت قد أجريت الدورة التدريبية حول بدء استخدام Notifications API، ستلاحظ أنّه تم استخدام الدالة requestPermission هنا. والفرق الوحيد هو أنّه يتم الآن أيضًا تعديل واجهة المستخدم بعد حلّ طلب الإذن.

    • تعمل الدالة updateUI على إعادة تحميل جميع أزرار التطبيق ورسائله.

    • تُجري الدالة initializePage عملية رصد للميزات المتعلّقة بإمكانية استخدام مهام الخدمة في المتصفّح وتُعدّل واجهة مستخدم التطبيق.

    • ينتظر النص البرمجي حتى يتم تحميل الصفحة ثم يُنشئها.

  2. في Glitch المضمّن، افتح public/service-worker.js.

    وكما يشير الاسم، ستضيف رمزًا إلى التطبيق لتسجيل هذا الملف كأحد عمال الخدمة.

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

    ستضيف رمزًا إلى public/service-worker.js لمعالجة الإشعارات عند تلقّيها من الخدمة العاملة.

تسجيل مشغّل الخدمات

في هذه الخطوة، ستكتب رمزًا برمجيًا يتم تنفيذه عندما ينقر المستخدم على تسجيل عامل الخدمة في واجهة مستخدم التطبيق. سيؤدي هذا الرمز إلى تسجيل public/service-worker.js كعامل خدمة.

  1. في محرِّر Glitch المضمّن، افتح public/index.js. استبدِل الدالة registerServiceWorker بالرمز البرمجي التالي:

    // Use the Service Worker API to register a service worker.
    async function registerServiceWorker() {
      await navigator.serviceWorker.register('./service-worker.js')
      updateUI();
    }
    

    يُرجى العِلم أنّ registerServiceWorker يستخدم بيان async function لتسهيل التعامل مع الوعود. يتيح لك ذلك await القيمة التي تمّ حلّها Promise. على سبيل المثال، تنتظر الدالة أعلاه نتيجة تسجيل مشغّل خدمات قبل تعديل واجهة المستخدم. اطّلِع على await على MDN للحصول على مزيد من المعلومات.

  2. والآن بعد أن أصبح بإمكان المستخدم تسجيل عامل خدمة، يمكنك الحصول على إشارة إلى عنصر تسجيل عامل الخدمة. في public/index.js، استبدِل الدالة getRegistration بالرمز البرمجي التالي:

    // Get the current service worker registration.
    function getRegistration() {
      return navigator.serviceWorker.getRegistration();
    }
    

    تستخدِم الدالة أعلاه Service Worker API للحصول على تسجيل مشغّل الخدمة الحالي، في حال توفّره. ويسهّل ذلك الحصول على مرجع لتسجيل الخدمة.

  • لإكمال وظيفة تسجيل مشغّل الخدمة، أضِف رمزًا لإلغاء تسجيل مشغّل الخدمة. استبدِل الدالة unRegisterServiceWorker بالرمز البرمجي التالي:

    // Unregister a service worker, then update the UI.
    async function unRegisterServiceWorker() {
      // Get a reference to the service worker registration.
      let registration = await getRegistration();
      // Await the outcome of the unregistration attempt
      // so that the UI update is not superceded by a
      // returning Promise.
      await registration.unregister();
      updateUI();
    }
    

في علامة التبويب التي تعرض التطبيق المباشر، أعِد تحميل الصفحة. من المفترض أن يعمل الزرّان تسجيل مشغّل الخدمات وإلغاء تسجيل مشغّل الخدمات الآن.

إرسال إشعارات إلى الخدمة العاملة

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

في محرِّر Glitch المضمّن، افتح public/index.js واستبدِل الدالة sendNotification بالرمز البرمجي التالي:

// Create and send a test notification to the service worker.
async function sendNotification() {
  // Use a random number as part of the notification data
  // (so you can tell the notifications apart during testing!)
  let randy = Math.floor(Math.random() * 100);
  let notification = {
    title: 'Test ' + randy,
    options: { body: 'Test body ' + randy }
  };
  // Get a reference to the service worker registration.
  let registration = await getRegistration();
  // Check that the service worker registration exists.
  if (registration) {
    // Check that a service worker controller exists before
    // trying to access the postMessage method.
    if (navigator.serviceWorker.controller) {
      navigator.serviceWorker.controller.postMessage(notification);
    } else {
      console.log('No service worker controller found. Try a soft reload.');
    }
  }
}

في ما يلي ما تفعله هذه التعليمة البرمجية:

  • sendNotification هي دالة غير متزامنة، لذا يمكنك استخدام await للحصول على إشارة إلى تسجيل الخدمة العاملة.

  • تُرسِل طريقة postMessage الخاصة بعملية الخدمة البيانات من التطبيق إلى عملية الخدمة. راجِع مستندات MDN حول دالة postMessage للحصول على مزيد من المعلومات.

  • يتحقّق الرمز من توفّر السمة navigator.serviceWorker.controller قبل محاولة الوصول إلى الدالة postMessage. سيكون navigator.serviceWorker.controller هو null إذا لم يكن هناك مشغّل خدمة نشط، أو إذا تمت إعادة تحميل الصفحة بشكلٍ قسري (Shift+إعادة تحميل). يمكنك الاطّلاع على مستندات وحدة تحكّم ServiceWorker على MDN للحصول على مزيد من المعلومات.

معالجة الإشعارات في الخدمة العاملة

في هذه الخطوة، ستكتب رمزًا في الخدمة العاملة يعالج الرسائل المنشورة عليها ويعرض الإشعارات للمستخدم.

في محرِّر Glitch المضمّن، افتح public/service-worker.js. أضِف الرمز البرمجي التالي إلى نهاية الملف:

// Show notification when received
self.addEventListener('message', (event) => {
  let notification = event.data;
  self.registration.showNotification(
    notification.title,
    notification.options
  ).catch((error) => {
    console.log(error);
  });
});

في ما يلي شرح سريع:

  • self هو إشارة إلى عامل الخدمة نفسه.

  • على الرغم من أنّ الخدمة العاملة تتعامل الآن مع عرض الإشعارات، لا تزال واجهة المستخدم الرئيسية للتطبيق مسؤولة عن الحصول على إذن الإشعارات من المستخدم. في حال عدم منح الإذن، يتم رفض الوعد الذي يعرضه showNotification. يستخدم الرمز أعلاه رمز catch لتجنُّب خطأ رفض Promise لم يتمّ اكتشافه والتعامل مع هذا الخطأ بشكلٍ أكثر سلاسة.

إذا واجهت مشكلة، يمكنك الانتقال إلى glitch.com/edit/#!/codelab-notifications-service-worker-completed للاطّلاع على الرمز البرمجي المكتمل.

انتقِل إلى ورشة رموز البرمجة التالية في هذه السلسلة: إنشاء خادم إشعارات فورية.