استيراد وتصدير هويات أجهزة IoT Hub بشكل مجمع

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

ملاحظة

أضاف IoT Hub مؤخرا دعما للشبكة الافتراضية في عدد محدود من المناطق. تؤمن هذه الميزة عمليات الاستيراد والتصدير وتزيل الحاجة إلى تمرير المفاتيح للمصادقة. في البداية، يتوفر دعم الشبكة الافتراضية فقط في هذه المناطق: WestUS2وEastUSوSouthCentralUS. لمعرفة المزيد حول دعم الشبكة الافتراضية واستدعاءات واجهة برمجة التطبيقات لتنفيذه، راجع دعم IoT Hub للشبكات الافتراضية.

تتم عمليات الاستيراد والتصدير في سياق الوظائف التي تمكنك من تنفيذ عمليات الخدمة المجمعة مقابل مركز إنترنت الأشياء.

تتضمن الفئة RegistryManager الأساليب ExportDevicesAsync وImportDevicesAsync التي تستخدم إطار العمل . تمكنك هذه الطرق من تصدير سجل هوية مركز إنترنت الأشياء بالكامل واستيراده ومزامنته.

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

ما هي الوظائف؟

تستخدم عمليات تسجيل الهوية نظام المهام عند العملية:

  • لديه وقت تنفيذ طويل محتمل مقارنة بعمليات وقت التشغيل القياسية.

  • إرجاع كمية كبيرة من البيانات إلى المستخدم.

بدلا من انتظار مكالمة API واحدة أو حظرها على نتيجة العملية ، تقوم العملية بشكل غير متزامن بإنشاء مهمة لمركز إنترنت الأشياء هذا. ثم تقوم العملية على الفور بإرجاع كائن JobProperties .

يوضح مقتطف التعليمات البرمجية C # التالي كيفية إنشاء مهمة تصدير:

// Call an export job on the IoT Hub to retrieve all devices
JobProperties exportJob = await 
  registryManager.ExportDevicesAsync(containerSasUri, false);

ملاحظة

لاستخدام فئة RegistryManager في التعليمات البرمجية C# الخاصة بك، أضف حزمة Microsoft.Azure.Devices NuGet إلى مشروعك. الفئة RegistryManager في مساحة اسم Microsoft.Azure.Devices.

يمكنك استخدام فئة RegistryManager للاستعلام عن حالة المهمة باستخدام بيانات تعريف JobProperties التي تم إرجاعها. لإنشاء مثيل من فئة "إدارة التسجيل" ، استخدم الأسلوب CreateFromConnectionString .

RegistryManager registryManager =
  RegistryManager.CreateFromConnectionString("{your IoT Hub connection string}");

للعثور على سلسلة الاتصال لمركز إنترنت الأشياء، في مدخل Azure:

  • انتقل إلى مركز إنترنت الأشياء الخاص بك.

  • حدد سياسات الوصول المشترك.

  • حدد سياسة، مع مراعاة الأذونات التي تحتاجها.

  • انسخ سلسلة الاتصال من اللوحة الموجودة على الجانب الأيسر من الشاشة.

يوضح مقتطف التعليمات البرمجية C # التالي كيفية إجراء الاستطلاع كل خمس ثوان لمعرفة ما إذا كانت المهمة قد انتهت من التنفيذ:

// Wait until job is finished
while(true)
{
  exportJob = await registryManager.GetJobAsync(exportJob.JobId);
  if (exportJob.Status == JobStatus.Completed || 
      exportJob.Status == JobStatus.Failed ||
      exportJob.Status == JobStatus.Cancelled)
  {
    // Job has finished executing
    break;
  }

  await Task.Delay(TimeSpan.FromSeconds(5));
}

ملاحظة

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

حدود مهام استيراد/تصدير الجهاز

يسمح فقط ب 1 وظيفة استيراد أو تصدير جهاز نشط في وقت واحد لجميع طبقات IoT Hub. لدى IoT Hub أيضا حدود لمعدل عمليات الوظائف. لمعرفة المزيد، راجع المرجع - حصص IoT Hub والاختناق.

تصدير الأجهزة

استخدم الأسلوب ExportDevicesAsync لتصدير كامل سجل هوية مركز إنترنت الأشياء إلى حاوية نقطة تخزين Azure باستخدام توقيع وصول مشترك (SAS). للحصول على مزيد من المعلومات عن توقيعات الوصول المشارك، راجع منح الوصول المحدود إلى موارد Azure Storage باستخدام توقيعات الوصول المشاركة (SAS).

تمكنك هذه الطريقة من إنشاء نسخ احتياطية موثوقة لمعلومات جهازك في حاوية نقطية تتحكم فيها.

تتطلب طريقة ExportDevicesAsync معلمتين:

  • سلسلة تحتوي على عنوان URI لحاوية نقطة. يجب أن يحتوي عنوان URI هذا على رمز SAS المميز الذي يمنح حق الوصول إلى الكتابة إلى الحاوية. تقوم المهمة بإنشاء كتلة كتلة في هذه الحاوية لتخزين بيانات جهاز التصدير المتسلسلة. يجب أن يتضمن رمز SAS المميز هذه الأذونات:

    SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read 
       | SharedAccessBlobPermissions.Delete
    
  • منطقي يشير إلى ما إذا كنت تريد استبعاد مفاتيح المصادقة من بيانات التصدير الخاصة بك. إذا كانت خاطئة، يتم تضمين مفاتيح المصادقة في إخراج التصدير. وإلا، يتم تصدير المفاتيح على أنها فارغة.

يوضح مقتطف التعليمات البرمجية C # التالي كيفية بدء مهمة تصدير تتضمن مفاتيح مصادقة الجهاز في بيانات التصدير ثم الاستقصاء للإكمال:

// Call an export job on the IoT Hub to retrieve all devices
JobProperties exportJob = 
  await registryManager.ExportDevicesAsync(containerSasUri, false);

// Wait until job is finished
while(true)
{
    exportJob = await registryManager.GetJobAsync(exportJob.JobId);
    if (exportJob.Status == JobStatus.Completed || 
        exportJob.Status == JobStatus.Failed ||
        exportJob.Status == JobStatus.Cancelled)
    {
    // Job has finished executing
    break;
    }

    await Task.Delay(TimeSpan.FromSeconds(5));
}

تقوم الوظيفة بتخزين مخرجاتها في حاوية blob المقدمة ككتلة كتلة تحمل اسم devices.txt. تتكون بيانات الإخراج من بيانات جهاز JSON المتسلسل ، مع جهاز واحد لكل سطر.

يوضح المثال التالي بيانات الإخراج:

{"id":"Device1","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device2","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device3","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device4","eTag":"MA==","status":"disabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}
{"id":"Device5","eTag":"MA==","status":"enabled","authentication":{"symmetricKey":{"primaryKey":"abc=","secondaryKey":"def="}}}

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

{
   "id":"export-6d84f075-0",
   "eTag":"MQ==",
   "status":"enabled",
   "statusReason":"firstUpdate",
   "authentication":null,
   "twinETag":"AAAAAAAAAAI=",
   "tags":{
      "Location":"LivingRoom"
   },
   "properties":{
      "desired":{
         "Thermostat":{
            "Temperature":75.1,
            "Unit":"F"
         },
         "$metadata":{
            "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
            "$lastUpdatedVersion":2,
            "Thermostat":{
               "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
               "$lastUpdatedVersion":2,
               "Temperature":{
                  "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
                  "$lastUpdatedVersion":2
               },
               "Unit":{
                  "$lastUpdated":"2017-03-09T18:30:52.3167248Z",
                  "$lastUpdatedVersion":2
               }
            }
         },
         "$version":2
      },
      "reported":{
         "$metadata":{
            "$lastUpdated":"2017-03-09T18:30:51.1309437Z"
         },
         "$version":1
      }
   }
}

إذا كنت بحاجة إلى الوصول إلى هذه البيانات في التعليمات البرمجية ، فيمكنك بسهولة إلغاء تسلسل هذه البيانات باستخدام فئة ExportImportDevice . يوضح مقتطف التعليمات البرمجية C # التالي كيفية قراءة معلومات الجهاز التي تم تصديرها مسبقا إلى نقطة كتلة:

var exportedDevices = new List<ExportImportDevice>();

using (var streamReader = new StreamReader(await blob.OpenReadAsync(AccessCondition.GenerateIfExistsCondition(), null, null), Encoding.UTF8))
{
  while (streamReader.Peek() != -1)
  {
    string line = await streamReader.ReadLineAsync();
    var device = JsonConvert.DeserializeObject<ExportImportDevice>(line);
    exportedDevices.Add(device);
  }
}

استيراد الأجهزة

تمكنك طريقة ImportDevicesAsync في فئة RegistryManager من إجراء عمليات استيراد ومزامنة مجمعة في سجل هوية مركز إنترنت الأشياء. مثل الأسلوب ExportDevicesAsync، تستخدم طريقة ImportDevicesAsync إطار العمل.

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

تحذير

لا يمكن التراجع عن عملية استيراد. قم دائما بعمل نسخة احتياطية من بياناتك الموجودة باستخدام الأسلوب ExportDevicesAsync إلى حاوية نقطة أخرى قبل إجراء تغييرات مجمعة على سجل الهوية الخاص بك.

تأخذ طريقة ImportDevicesAsync معلمتين:

  • سلسلة تحتوي على عنوان URI لحاوية نقطة تخزين Azure لاستخدامها كإدخال للمهمة. يجب أن يحتوي عنوان URI هذا على رمز SAS المميز الذي يمنح حق الوصول للقراءة إلى الحاوية. يجب أن تحتوي هذه الحاوية على نقطة تحمل الاسم devices.txt تحتوي على بيانات الجهاز المتسلسل لاستيرادها إلى سجل الهوية الخاص بك. يجب أن تحتوي بيانات الاستيراد على معلومات الجهاز بنفس تنسيق JSON الذي تستخدمه مهمة ExportImportDevice عند إنشاء نقطة devices.txt . يجب أن يتضمن رمز SAS المميز هذه الأذونات:

    SharedAccessBlobPermissions.Read
    
  • سلسلة تحتوي على عنوان URI لحاوية نقطة تخزين Azure لاستخدامها كإخراج من المهمة. تقوم المهمة بإنشاء كتلة كتلة في هذه الحاوية لتخزين أية معلومات خطأ من مهمة الاستيراد المكتملة. يجب أن يتضمن رمز SAS المميز هذه الأذونات:

    SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read 
       | SharedAccessBlobPermissions.Delete
    

ملاحظة

يمكن أن تشير المعلمتان إلى نفس حاوية blob. تتيح المعلمات المنفصلة ببساطة مزيدا من التحكم في بياناتك لأن حاوية الإخراج تتطلب أذونات إضافية.

يوضح مقتطف التعليمات البرمجية C # التالي كيفية بدء مهمة استيراد:

JobProperties importJob = 
   await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

يمكن أيضا استخدام هذه الطريقة لاستيراد البيانات الخاصة بالجهاز التوأم. تنسيق إدخال البيانات هو نفسه التنسيق الموضح في قسم ExportDevicesAsync . وبهذه الطريقة، يمكنك إعادة استيراد البيانات المصدرة. $metadata اختياري.

سلوك الاستيراد

يمكنك استخدام الأسلوب ImportDevicesAsync لتنفيذ العمليات المجمعة التالية في سجل الهوية الخاص بك:

  • التسجيل المجمع للأجهزة الجديدة
  • عمليات الحذف المجمع للأجهزة الحالية
  • تغييرات الحالة المجمعة (تمكين الأجهزة أو تعطيلها)
  • التعيين المجمع لمفاتيح مصادقة الجهاز الجديدة
  • التجديد التلقائي المجمع لمفاتيح مصادقة الجهاز
  • تحديث مجمع للبيانات التوأم

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

إذا كان ملف الاستيراد يتضمن بيانات تعريف مزدوجة، فإن هذه البيانات الوصفية تحل محل بيانات التعريف التوأم الموجودة. إذا كان ملف الاستيراد لا يتضمن بيانات تعريف مزدوجة، تحديث بيانات التعريف فقط lastUpdateTime باستخدام الوقت الحالي.

استخدم خاصية importMode الاختيارية في بيانات تسلسل الاستيراد لكل جهاز للتحكم في عملية الاستيراد لكل جهاز. تحتوي الخاصية importMode على الخيارات التالية:

وضع الاستيراد الوصف
⁩إنشاء⁧ إذا لم يكن الجهاز موجودا بالمعرف المحدد، تسجيله حديثا. إذا كان الجهاز موجودا بالفعل، تتم كتابة خطأ إلى ملف السجل.
كريت أور تحديث إذا لم يكن الجهاز موجودا بالمعرف المحدد، تسجيله حديثا. إذا كان الجهاز موجودا بالفعل، تتم الكتابة فوق المعلومات الموجودة ببيانات الإدخال المقدمة بغض النظر عن قيمة eTag .
كريت أور تحديثإيفماتيغ إذا لم يكن الجهاز موجودا بالمعرف المحدد، تسجيله حديثا. إذا كان الجهاز موجودا بالفعل، استبدال المعلومات الموجودة ببيانات الإدخال المقدمة فقط إذا كان هناك تطابق ETag . إذا كان هناك عدم تطابق ETag ، تتم كتابة خطأ إلى ملف السجل.
حذف إذا كان الجهاز موجودا بالفعل مع المعرف المحدد، حذفه بغض النظر عن قيمة ETag . في حالة عدم وجود الجهاز، تتم كتابة خطأ إلى ملف السجل.
DeleteIfMatchETag إذا كان الجهاز موجودا بالفعل مع المعرف المحدد، حذفه فقط إذا كان هناك تطابق ETag . في حالة عدم وجود الجهاز، تتم كتابة خطأ إلى ملف السجل. إذا كان هناك عدم تطابق ETag، تتم كتابة خطأ إلى ملف السجل.
⁩تحديث⁧ إذا كان الجهاز موجودا بالفعل بالمعرف المحدد، الكتابة فوق المعلومات الموجودة ببيانات الإدخال المقدمة بغض النظر عن قيمة eTag . في حالة عدم وجود الجهاز، تتم كتابة خطأ إلى ملف السجل.
UpdateIfMatchETag إذا كان الجهاز موجودا بالفعل مع المعرف المحدد، يتم الكتابة فوق المعلومات الموجودة مع بيانات الإدخال المقدمة فقط إذا كان هناك تطابق ETag . إذا لم يكن الجهاز موجودا أو كان هناك عدم تطابق ETag ، تتم كتابة خطأ في ملف السجل.
تحديث التوأم إذا كان التوأم موجودا بالفعل مع المعرف المحدد ، استبدال المعلومات الموجودة ببيانات الإدخال المقدمة بغض النظر عن قيمة ETag الخاصة بالتوأم.
تحديثTwinIfMatchETag إذا كان التوأم موجودا بالفعل مع المعرف المحدد، يتم الكتابة فوق المعلومات الموجودة مع بيانات الإدخال المقدمة فقط إذا كان هناك تطابق في قيمة ETag الخاصة بالتوأم. تتم معالجة ETag الخاص بالتوأم بشكل مستقل عن ETag الخاص بالجهاز. إذا كان هناك عدم تطابق مع ETag الخاص بالتوأم الموجود، كتابة خطأ في ملف السجل.

ملاحظة

إذا لم تحدد بيانات التسلسل بشكل صريح علامة importMode لأحد الأجهزة، تعيينها افتراضيا لإنشاء OrUpdate أثناء عملية الاستيراد.

مثال على استيراد الأجهزة - إدارة حسابات الأجهزة المجمعة

يوضح نموذج التعليمات البرمجية C # التالي كيفية إنشاء هويات أجهزة متعددة التي:

  • تضمين مفاتيح المصادقة.
  • اكتب معلومات هذا الجهاز إلى نقطة كتلة.
  • استيراد الأجهزة إلى سجل الهوية.
// Provision 1,000 more devices
var serializedDevices = new List<string>();

for (var i = 0; i < 1000; i++)
{
  // Create a new ExportImportDevice
  // CryptoKeyGenerator is in the Microsoft.Azure.Devices.Common namespace
  var deviceToAdd = new ExportImportDevice()
  {
    Id = Guid.NewGuid().ToString(),
    Status = DeviceStatus.Enabled,
    Authentication = new AuthenticationMechanism()
    {
      SymmetricKey = new SymmetricKey()
      {
        PrimaryKey = CryptoKeyGenerator.GenerateKey(32),
        SecondaryKey = CryptoKeyGenerator.GenerateKey(32)
      }
    },
    ImportMode = ImportMode.Create
  };

  // Add device to the list
  serializedDevices.Add(JsonConvert.SerializeObject(deviceToAdd));
}

// Write the list to the blob
var sb = new StringBuilder();
serializedDevices.ForEach(serializedDevice => sb.AppendLine(serializedDevice));
await blob.DeleteIfExistsAsync();

using (CloudBlobStream stream = await blob.OpenWriteAsync())
{
  byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
  for (var i = 0; i < bytes.Length; i += 500)
  {
    int length = Math.Min(bytes.Length - i, 500);
    await stream.WriteAsync(bytes, i, length);
  }
}

// Call import using the blob to add new devices
// Log information related to the job is written to the same container
// This normally takes 1 minute per 100 devices
JobProperties importJob =
   await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

// Wait until job is finished
while(true)
{
  importJob = await registryManager.GetJobAsync(importJob.JobId);
  if (importJob.Status == JobStatus.Completed || 
      importJob.Status == JobStatus.Failed ||
      importJob.Status == JobStatus.Cancelled)
  {
    // Job has finished executing
    break;
  }

  await Task.Delay(TimeSpan.FromSeconds(5));
}

مثال على استيراد الأجهزة - الحذف المجمع

يوضح لك نموذج التعليمات البرمجية التالي كيفية حذف الأجهزة التي أضفتها باستخدام نموذج التعليمات البرمجية السابق:

// Step 1: Update each device's ImportMode to be Delete
sb = new StringBuilder();
serializedDevices.ForEach(serializedDevice =>
{
  // Deserialize back to an ExportImportDevice
  var device = JsonConvert.DeserializeObject<ExportImportDevice>(serializedDevice);

  // Update property
  device.ImportMode = ImportMode.Delete;

  // Re-serialize
  sb.AppendLine(JsonConvert.SerializeObject(device));
});

// Step 2: Write the new import data back to the block blob
await blob.DeleteIfExistsAsync();
using (CloudBlobStream stream = await blob.OpenWriteAsync())
{
  byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
  for (var i = 0; i < bytes.Length; i += 500)
  {
    int length = Math.Min(bytes.Length - i, 500);
    await stream.WriteAsync(bytes, i, length);
  }
}

// Step 3: Call import using the same blob to delete all devices
importJob = await registryManager.ImportDevicesAsync(containerSasUri, containerSasUri);

// Wait until job is finished
while(true)
{
  importJob = await registryManager.GetJobAsync(importJob.JobId);
  if (importJob.Status == JobStatus.Completed || 
      importJob.Status == JobStatus.Failed ||
      importJob.Status == JobStatus.Cancelled)
  {
    // Job has finished executing
    break;
  }

  await Task.Delay(TimeSpan.FromSeconds(5));
}

احصل على الحاوية SAS URI

يوضح لك نموذج التعليمات البرمجية التالي كيفية إنشاء SAS URI باستخدام أذونات القراءة والكتابة والحذف لحاوية blob:

static string GetContainerSasUri(CloudBlobContainer container)
{
  // Set the expiry time and permissions for the container.
  // In this case no start time is specified, so the
  // shared access signature becomes valid immediately.
  var sasConstraints = new SharedAccessBlobPolicy();
  sasConstraints.SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24);
  sasConstraints.Permissions = 
    SharedAccessBlobPermissions.Write | 
    SharedAccessBlobPermissions.Read | 
    SharedAccessBlobPermissions.Delete;

  // Generate the shared access signature on the container,
  // setting the constraints directly on the signature.
  string sasContainerToken = container.GetSharedAccessSignature(sasConstraints);

  // Return the URI string for the container,
  // including the SAS token.
  return container.Uri + sasContainerToken;
}

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

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

تحتوي مقالة الاستنساخ على عينة عمل مقترنة بها، وهي موجودة في عينات IoT C# في هذه الصفحة: Azure IoT Samples for C#‎، مع المشروع هو ImportExportDevicesSample. يمكنك تنزيل العينة وتجربتها ؛ هناك إرشادات في مقالة كيفية استنساخ مركز إنترنت الأشياء .

لمعرفة المزيد حول إدارة Azure IoT Hub، راجع المقالات التالية:

لمزيد من استكشاف إمكانات IoT Hub، راجع:

لاستكشاف استخدام خدمة توفير الأجهزة IoT Hub لتمكين إدارة الحسابات بدون لمس وفي الوقت المناسب، راجع: