جدولة وظائف البث (Node.js)

استخدم Azure IoT Hub لجدولة المهام التي تحدث ملايين الأجهزة وتعقبها. استخدام الوظائف لإجراء ما يلي:

  • تحديث الخصائص المطلوبة
  • تحديث العلامات
  • استدعاء أساليب مباشرة

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

في المقالات التالية نتعرف على المزيد حول كل من هذه الإمكانات:

ملاحظة

الميزات الموضحة في هذه المقالة متوفرة فقط في المستوى القياسي لـ IoT Hub. لمزيد من المعلومات حول مستويات IoT Hub الأساسية والقياسية/المجانية، راجع اختيار طبقة IoT Hub المناسبة للحل الخاص بك.

توضح لك هذه المقالة كيفية إنشاء تطبيقين Node.js:

  • تطبيق جهاز محاكاة Node.js simDevice.js، ينفذ أسلوبًا مباشرًا يسمى lockDoor، والذي يمكن استدعاؤه بواسطة التطبيق الخلفي.

  • تطبيق وحدة تحكم Node.js، scheduleJobService.js، الذي ينشئ وظيفتين. تستدعي إحدى الوظائف الأسلوب المباشر lockDoor وترسل مهمة أخرى تحديثات الخصائص المطلوبة إلى أجهزة متعددة.

ملاحظة

راجع Azure IoT SDKs لمزيد من المعلومات حول أدوات SDK المتوفرة لإنشاء كل من الجهاز والتطبيقات الخلفية.

المتطلبات الأساسية

  • مركز IoT. أنشئ واحدًا باستخدام CLI أو مدخل Azure.

  • جهاز مسجل. سجَل واحداً في مدخل Microsoft Azure.

  • Node.js الإصدار 10.0.x أو أحدث. يصف إعداد بيئة التطوير الخاصة بك كيفية تثبيت Node.js في هذه المقالة على نظامي التشغيل Windows أو Linux.

  • تأكد من أن المنفذ 8883 مفتوح في جدار الحماية الخاص بك. يستخدم نموذج الجهاز في هذه المقالة بروتوكول MQTT، الذي يتصل عبر المنفذ 8883. قد يتم حظر هذا المنفذ في بعض بيئات شبكات الشركات والتعليمية. لمزيد من المعلومات وطرق التغلب على هذه المشكلة، يرجى مراجعة الاتصال بمركز IoT (MQTT).

إنشاء تطبيق جهاز محاكاة

في هذا القسم، تقوم بإنشاء تطبيق وحدة تحكم Node.js يستجيب لطريقة مباشرة تستدعيها السحابة، والتي تقوم بتشغيل طريقة lockDoor محاكاة.

  1. قم بإنشاء مجلد فارغ جديد يسمى simDevice. في المجلد simDevice، قم بإنشاء ملف package.json باستخدام الأمر التالي في موجه الأوامر. قبول جميع الافتراضيات:

    npm init
    
  2. في موجه الأوامر الخاص بك في المجلد simDevice، قم بتشغيل الأمر التالي لتثبيت حزمة SDK وحزمة azure-iot-device وazure-iot-device-mqtt:

    npm install azure-iot-device azure-iot-device-mqtt --save
    
  3. باستخدام محرر نصوص، قم بإنشاء ملف simDevice.js جديد في المجلد simDevice.

  4. أضف عبارات 'require' التالية في بداية ملف simDevice.js :

    'use strict';
    
    var Client = require('azure-iot-device').Client;
    var Protocol = require('azure-iot-device-mqtt').Mqtt;
    
  5. أضف متغير connectionString واستخدمه لإنشاء مثيل Client. استبدل قيمة العنصر النائب {yourDeviceConnectionString} بسلسلة اتصال الجهاز التي نسختها مسبقاً.

    var connectionString = '{yourDeviceConnectionString}';
    var client = Client.fromConnectionString(connectionString, Protocol);
    
  6. أضف الوظيفة التالية للتعامل مع طريقة lockDoor.

    var onLockDoor = function(request, response) {
    
        // Respond the cloud app for the direct method
        response.send(200, function(err) {
            if (err) {
                console.error('An error occurred when sending a method response:\n' + err.toString());
            } else {
                console.log('Response to method \'' + request.methodName + '\' sent successfully.');
            }
        });
    
        console.log('Locking Door!');
    };
    
  7. أضف التعليمة البرمجية التالية لتسجيل المعالج للأسلوب lockDoor.

    client.open(function(err) {
         if (err) {
             console.error('Could not connect to IotHub client.');
         }  else {
             console.log('Client connected to IoT Hub. Register handler for lockDoor direct method.');
             client.onDeviceMethod('lockDoor', onLockDoor);
         }
    });
    
  8. احفظ وأغلق ملف simDevice.js.

ملاحظة

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

الحصول على سلسلة اتصال IoT Hub

في هذه المقالة، تقوم بإنشاء خدمة خلفية تقوم بجدولة مهمة لاستدعاء أسلوب مباشر على أحد الأجهزة، وتقوم بجدولة مهمة لتحديث الجهاز المزدوج، وتراقب تقدم كل وظيفة. لتنفيذ هذه العمليات، تحتاج خدمتك إلى أذونات قراءة السجل وكتابة السجل. افتراضيًا، يتم إنشاء كافة مراكز IoT باستخدام نهج الوصول المشترك يسمى registryReadWrite التي تمنح هذه الأذونات.

للحصول على سلسلة اتصال IoT Hub لنهج registryReadWrite، اتبع الخطوات التالية:

  1. في مدخل Microsoft Azure، حدد Resource groups. حدد مجموعة الموارد حيث يوجد المركز الخاص بك، ثم حدد المركز الخاص بك من قائمة الموارد.

  2. في الجزء الأيسر من مركزك، قم بتحديد سياسات الوصول المشترك.

  3. من قائمة النهج، حدد نهج registryReadWrite.

  4. انسخ سلسلة الاتصال الأساسية واحفظ القيمة.

    لقطة شاشة تعرض الطريقة لاستعادة سلسلة الاتصال

لمزيد من المعلومات حول نهج الوصول المشترك لمركز IoT والأذونات، راجع التحكم في الوصول والأذونات.

جدولة الوظائف لاستدعاء طريقة مباشرة وتحديث خصائص جهاز مزدوج

في هذا القسم، تقوم بإنشاء تطبيق وحدة تحكم Node.js الذي يبدأ تشغيل lockDoor عن بُعد على جهاز باستخدام طريقة مباشرة وتحديث خصائص الجهاز المزدوج.

  1. قم بإنشاء مجلد فارغ جديد يسمى scheduleJobService. في المجلد scheduleJobService، قم بإنشاء ملف package.json باستخدام الأمر التالي في موجه الأوامر. قبول جميع الافتراضيات:

    npm init
    
  2. في موجه الأوامر الخاص بك في المجلد scheduleJobService، قم بتشغيل الأمر التالي لتثبيت حزمة azure-iothub Device SDK وحزمة azure-iot-device-mqtt :

    npm install azure-iothub uuid --save
    
  3. باستخدام محرر نصوص، قم بإنشاء ملف scheduleJobService.js جديد في المجلد scheduleJobService.

  4. أضف عبارات "تتطلب" التالية في بداية ملف scheduleJobService.js :

    'use strict';
    
    var uuid = require('uuid');
    var JobClient = require('azure-iothub').JobClient;
    
  5. إضافة تعريفات المتغير التالية. استبدل قيمة العنصر النائب {iothubconnectionstring} بالقيمة التي نسختها في الحصول على سلسلة اتصال مركز إنترنت الأشياء. إذا قمت بتسجيل جهاز مختلف عن myDeviceId، فتأكد من تغييره في حالة الاستعلام.

    var connectionString = '{iothubconnectionstring}';
    var queryCondition = "deviceId IN ['myDeviceId']";
    var startTime = new Date();
    var maxExecutionTimeInSeconds =  300;
    var jobClient = JobClient.fromConnectionString(connectionString);
    
  6. أضف الوظيفة التالية التي تُستخدم لمراقبة تنفيذ المهمة:

    function monitorJob (jobId, callback) {
        var jobMonitorInterval = setInterval(function() {
            jobClient.getJob(jobId, function(err, result) {
            if (err) {
                console.error('Could not get job status: ' + err.message);
            } else {
                console.log('Job: ' + jobId + ' - status: ' + result.status);
                if (result.status === 'completed' || result.status === 'failed' || result.status === 'cancelled') {
                clearInterval(jobMonitorInterval);
                callback(null, result);
                }
            }
            });
        }, 5000);
    }
    
  7. أضف التعليمة البرمجية التالي لجدولة المهمة التي تستدعي طريقة الجهاز:

    var methodParams = {
        methodName: 'lockDoor',
        payload: null,
        responseTimeoutInSeconds: 15 // Timeout after 15 seconds if device is unable to process method
    };
    
    var methodJobId = uuid.v4();
    console.log('scheduling Device Method job with id: ' + methodJobId);
    jobClient.scheduleDeviceMethod(methodJobId,
                                queryCondition,
                                methodParams,
                                startTime,
                                maxExecutionTimeInSeconds,
                                function(err) {
        if (err) {
            console.error('Could not schedule device method job: ' + err.message);
        } else {
            monitorJob(methodJobId, function(err, result) {
                if (err) {
                    console.error('Could not monitor device method job: ' + err.message);
                } else {
                    console.log(JSON.stringify(result, null, 2));
                }
            });
        }
    });
    
  8. أضف التعليمة البرمجية التالي لجدولة مهمة تحديث الجهاز التوأم:

    var twinPatch = {
       etag: '*',
       properties: {
           desired: {
               building: '43',
               floor: 3
           }
       }
    };
    
    var twinJobId = uuid.v4();
    
    console.log('scheduling Twin Update job with id: ' + twinJobId);
    jobClient.scheduleTwinUpdate(twinJobId,
                                queryCondition,
                                twinPatch,
                                startTime,
                                maxExecutionTimeInSeconds,
                                function(err) {
        if (err) {
            console.error('Could not schedule twin update job: ' + err.message);
        } else {
            monitorJob(twinJobId, function(err, result) {
                if (err) {
                    console.error('Could not monitor twin update job: ' + err.message);
                } else {
                    console.log(JSON.stringify(result, null, 2));
                }
            });
        }
    });
    
  9. احفظ وأغلق ملف scheduleJobService.js.

تشغيل التطبيقات

أنت الآن جاهز لتشغيل التطبيقات.

  1. في موجه الأوامر في المجلد simDevice، قم بتشغيل الأمر التالي لبدء الاستماع لطريقة إعادة التشغيل المباشرة.

    node simDevice.js
    
  2. في موجه الأوامر في المجلد scheduleJobService، قم بتشغيل الأمر التالي لتشغيل المهام لقفل الباب وتحديث التوأم

    node scheduleJobService.js
    
  3. ترى استجابة الجهاز للطريقة المباشرة وحالة الوظيفة في وحدة التحكم.

    يوضح ما يلي استجابة الجهاز للطريقة المباشرة:

    Simulated device app output

    يوضح ما يلي وظائف جدولة الخدمة للطريقة المباشرة والتحديث الثنائي للجهاز، والمهام قيد التشغيل حتى الاكتمال:

    تشغيل تطبيق الجهاز المحاكى

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

في هذه المقالة، قمت بجدولة المهام لتشغيل أسلوب مباشر وتحديث خصائص توأم الجهاز.

لمتابعة استكشاف IoT Hub وأنماط إدارة الجهاز، قم بتحديث صورة في البرنامج التعليمي Device Update for Azure IoT Hub باستخدام Raspberry Pi 3 B + صورة مرجعية.