إنشاء Websocket موثوق به باستخدام البروتوكول الفرعي

عند انخفاض اتصالات عميل Websocket بسبب مشكلات متقطعة في الشبكة، يمكن فقدان الرسائل. في نظام pub/sub، يتم فصل الناشرين عن المشتركين، لذلك قد لا يكتشف الناشرون انقطاع الاتصال أو فقدان الرسائل للمشتركين. من الضروري للعملاء التغلب على مشكلات الشبكة المتقطعة والحفاظ على تسليم الرسائل الموثوق به. لتحقيق ذلك، يمكنك إنشاء عميل Websocket موثوق به بمساعدة البروتوكولات الفرعية ل Azure Web PubSub الموثوق بها.

بروتوكول موثوق به

تدعم خدمة Web PubSub اثنين من البروتوكولات json.reliable.webpubsub.azure.v1 الفرعية الموثوق بها و protobuf.reliable.webpubsub.azure.v1. يجب على العملاء اتباع أجزاء الناشر والمشترك والاسترداد من البروتوكول الفرعي لتحقيق الموثوقية. قد يؤدي الفشل في تنفيذ البروتوكول الفرعي بشكل صحيح إلى عدم عمل تسليم الرسالة كما هو متوقع أو إنهاء الخدمة للعميل بسبب انتهاكات البروتوكول.

الطريقة السهلة - استخدام SDK للعميل

أبسط طريقة لإنشاء عميل موثوق به هي استخدام Client SDK. يقوم Client SDK بتنفيذ مواصفات عميل Web PubSub واستخدامه json.reliable.webpubsub.azure.v1 بشكل افتراضي. يرجى الرجوع إلى النشر/الاشتراك بين العملاء للبدء السريع.

الطريقة الصعبة - تنفيذ باليد

يرشدك البرنامج التعليمي التالي خلال الجزء الهام من تنفيذ مواصفات عميل Web PubSub. هذا الدليل ليس للأشخاص الذين يبحثون عن بداية سريعة ولكن الذين يريدون معرفة مبدأ تحقيق الموثوقية. للبدء السريع، يرجى استخدام Client SDK.

بدء

لاستخدام البروتوكولات الفرعية الموثوق بها، يجب عليك تعيين البروتوكول الفرعي عند إنشاء اتصالات Websocket. في JavaScript، يمكنك استخدام التعليمات البرمجية التالية:

  • استخدم البروتوكول الفرعي الموثوق به ل Json:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "json.reliable.webpubsub.azure.v1"
    );
    
  • استخدم Protobuf subprotocol الموثوق به:

    var pubsub = new WebSocket(
      "wss://test.webpubsub.azure.com/client/hubs/hub1",
      "protobuf.reliable.webpubsub.azure.v1"
    );
    

استرداد الاتصال

الاتصال الاسترداد هو أساس تحقيق الموثوقية ويجب تنفيذه عند استخدام json.reliable.webpubsub.azure.v1 البروتوكولين وprotobuf.reliable.webpubsub.azure.v1.

تعتمد اتصالات Websocket على TCP. عندما لا ينخفض الاتصال، تكون الرسائل بدون فقدان ويتم تسليمها بالترتيب. لمنع فقدان الرسائل عبر الاتصالات التي تم إسقاطها، تحتفظ خدمة Web PubSub بمعلومات حالة الاتصال، بما في ذلك معلومات المجموعة والرسالة. يتم استخدام هذه المعلومات لاستعادة العميل عند استرداد الاتصال

عندما يعيد العميل الاتصال بالخدمة باستخدام البروتوكولات الفرعية الموثوق بها، سيتلقى العميل رسالة Connected تحتوي على connectionId و reconnectionToken. connectionId يحدد جلسة الاتصال في الخدمة.

{
  "type": "system",
  "event": "connected",
  "connectionId": "<connection_id>",
  "reconnectionToken": "<reconnection_token>"
}

بمجرد انخفاض اتصال WebSocket، يجب أن يحاول العميل إعادة الاتصال بنفس الشيء connectionId لاستعادة نفس جلسة العمل. لا يحتاج العملاء إلى التفاوض مع الخادم والحصول على access_token. بدلا من ذلك، لاسترداد الاتصال، يجب على العميل إجراء طلب اتصال WebSocket مباشرة إلى الخدمة باسم مضيف الخدمة و connection_idو reconnection_token:

wss://<service-endpoint>/client/hubs/<hub>?awps_connection_id=<connection_id>&awps_reconnection_token=<reconnection_token>

قد يفشل استرداد الاتصال إذا لم يتم استرداد مشكلة الشبكة بعد. يجب أن يستمر العميل في إعادة المحاولة لإعادة الاتصال حتى:

  1. يتم إغلاق اتصال Websocket مع رمز الحالة 1008. تعني التعليمة البرمجية للحالة أنه تمت إزالة connectionId من الخدمة.
  2. يستمر فشل الاسترداد في الحدوث لأكثر من دقيقة واحدة.

الناشر

يطلق على العملاء الذين يرسلون الأحداث إلى معالجات الأحداث أو ينشرون رسائل إلى عملاء آخرين الناشرين. يجب على الناشرين تعيين ackId في الرسالة لتلقي إشعار من خدمة Web PubSub بأن نشر الرسالة كان ناجحا أم لا.

ackId هو معرف الرسالة، يجب أن تستخدم كل رسالة جديدة معرفا فريدا. يجب استخدام الأصل ackId عند إعادة إرسال رسالة.

عينة من رسالة إرسال مجموعة:

{
  "type": "sendToGroup",
  "group": "group1",
  "dataType": "text",
  "data": "text data",
  "ackId": 1
}

نموذج استجابة ack:

{
  "type": "ack",
  "ackId": 1,
  "success": true
}

عندما تقوم خدمة Web PubSub بإرجاع استجابة ack مع success: true، تمت معالجة الرسالة بواسطة الخدمة، ويمكن للعميل توقع تسليم الرسالة إلى جميع المشتركين.

عندما تواجه الخدمة خطأ داخليا عابرا ولا يمكن إرسال الرسالة إلى المشترك، سيتلقى الناشر ack مع success: false. يجب على الناشر قراءة الخطأ لتحديد ما إذا كان يجب إعادة إرسال الرسالة أم لا. إذا كانت الرسالة متراجعة، يجب استخدام نفس الشيء ackId .

{
  "type": "ack",
  "ackId": 1,
  "success": false,
  "error": {
    "name": "InternalServerError",
    "message": "Internal server error"
  }
}

Message Failure

إذا فقدت استجابة ack للخدمة بسبب إسقاط اتصال WebSocket، يجب على الناشر إعادة إرسال الرسالة بنفس الطريقة ackId بعد الاسترداد. عند معالجة الرسالة مسبقا بواسطة الخدمة، سترسل ack تحتوي على خطأ Duplicate . يجب أن يتوقف الناشر عن إعادة إرسال هذه الرسالة.

{
  "type": "ack",
  "ackId": 1,
  "success": false,
  "error": {
    "name": "Duplicate",
    "message": "Message with ack-id: 1 has been processed"
  }
}

Message duplicated

المشترك

يطلق على العملاء الذين يتلقون رسائل من معالجات الأحداث أو الناشرين اسم المشتركين. عند انخفاض الاتصالات بسبب مشكلات في الشبكة، لا تعرف خدمة Web PubSub عدد الرسائل التي تم إرسالها إلى المشتركين. لتحديد الرسالة الأخيرة التي تلقاها المشترك، ترسل الخدمة رسالة بيانات تحتوي على sequenceId. يستجيب المشترك برسالة سلسلة ack:

عينة تسلسل ack:

{
  "type": "sequenceAck",
  "sequenceId": 1
}

sequenceId هو رقم تزايدي uint64 في جلسة عمل معرف الاتصال. يجب على المشتركين تسجيل أكبر sequenceId عدد تلقاه، وقبول الرسائل ذات الحجم الأكبر sequenceIdفقط، وإفلات الرسائل ذات الحجم الأصغر أو المتساوي sequenceId. يجب أن يقوم المشترك بالتكديس مع أكبر sequenceId عدد سجله، بحيث يمكن للخدمة تخطي رسائل إعادة تسليم الرسائل التي تلقاها المشتركون بالفعل. على سبيل المثال، إذا استجاب المشترك باستخدام sequenceAcksequenceId: 5، فستعيد الخدمة إرسال الرسائل التي sequenceId يزيد حجمها عن 5 رسائل فقط.

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