MQTT هو بروتوكول خفيف لتبادل الرسائل، يتيح للأجهزة إرسال رسائل صغيرة عبر خادم مركزي يُسمّى الوسيط، بدلًا من التواصل مباشرةً بعضها مع بعض. ينشر الجهاز رسالة تحت اسم يُسمّى موضوعًا، أو topic، ويتلقى كل برنامج مشترك في ذلك الموضوع نسخة منها. هذا الترتيب البسيط هو سبب انتشار MQTT في المستشعرات والبوابات الصناعية ومحاور Zigbee وأنظمة المباني.

صمّمه آندي ستانفورد-كلارك من IBM وآرلن نيبر، الذي كان يعمل آنذاك في Arcom Control Systems، عام 1999 لمراقبة خطوط النفط عبر وصلات أقمار صناعية بطيئة ومكلفة. وما زالت هذه النشأة تفسّر معظم خصائصه، من الحزم الصغيرة جدًا إلى الطريقة التي يتيح بها للجهاز ترك رسالة تُعلن انقطاعه عن الشبكة.

الخلاصة

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

فيمَ يُستخدم MQTT؟

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

هناك ثلاث خصائص تفسّر ملاءمته لهذه المهام. أولًا، حجم البيانات الإضافية صغير جدًا: قد لا يتجاوز الترويس الثابت لحزمة MQTT بايتين، في حين يتضمن طلب HTTP عادةً بضع مئات من البايتات في الترويسات قبل القراءة نفسها. وعندما يرسل الجهاز رقمًا كل بضع ثوانٍ، يتراكم هذا الفارق.

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

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

كثير من المعدات التي تستحق المراقبة لا تدعم MQTT مباشرةً. تستخدم عدادات الطاقة ومغيرات السرعة عادةً Modbus، وتستخدم وحدات التحكم في المباني BACnet، وتتيح آلات المصانع OPC UA، بينما تعتمد مستشعرات لاسلكية كثيرة في المباني على Zigbee. والحل المعتاد هو بوابة طرفية في الموقع تقرأ البروتوكول الأصلي وتنشر القيم في رسائل MQTT. قد تكون جهازًا صناعيًا من Advantech أو Moxa، أو حاسوبًا صغيرًا يشغّل Node-RED، أو محور Zigbee2MQTT ينشر بيانات كل جهاز Zigbee بصيغة JSON. ومن تلك النقطة، لا يحتاج باقي النظام إلا إلى فهم بروتوكول واحد.

لا يناسب MQTT كل مهمة. فكثيرًا ما يكون HTTP أبسط للتبادلات المتباعدة القائمة على الطلب والرد، مثل جهاز يرفع تقريرًا واحدًا يوميًا أو تطبيق يجلب ملف إعدادات. والمستشعر الذي يعمل ببطارية صُمّمت لتدوم سنوات لا يستطيع عادةً إبقاء اتصال TCP مفتوحًا، ولذلك يستخدم غالبًا اتصالًا لاسلكيًا منخفض الاستهلاك مثل LoRaWAN، ويصل إلى باقي النظام عبر بوابة. كما أن بث الفيديو ونقل الملفات الكبيرة يحتاجان إلى بروتوكولات أخرى.

ما هو خادم MQTT؟

خادم MQTT هو البرنامج الذي تتصل به جميع الأجهزة والتطبيقات. ويُسمّى عادةً وسيطًا لأنه لا يقدّم صفحات مثل خادم الويب. يستقبل كل رسالة، ويتحقق من موضوعها، ثم يرسل نسخة إلى كل عميل لديه اشتراك مطابق. من الوسطاء المعروفين Eclipse Mosquitto المفتوح المصدر، وEMQX وHiveMQ، إلى جانب خدمات سحابية مثل AWS IoT Core.

الموضوعات سلاسل نصية مقسّمة إلى مستويات بشرطات مائلة، على نحو يشبه مسار الملف. فقد ينشر مستشعر غرفة تبريد في plant1/coldroom3/temperature، وينشر مستشعر باب في plant1/dock2/door. لا أحد ينشئ الموضوع مسبقًا؛ فهو يوجد بمجرد النشر فيه. لهذا تتفق الفرق مبكرًا على بنية الأسماء، لأن الوسيط يقبل أي كتابة، والخطأ المطبعي يصبح ببساطة موضوعًا جديدًا لا يستمع إليه أحد.

يمكن للمشتركين استخدام رمزين بديلين. تطابق علامة الجمع مستوى واحدًا فقط، ولذلك يتلقى الاشتراك في plant1/+/temperature درجات حرارة جميع غرف الموقع 1. وتطابق علامة المربع كل ما يقع تحت مستوى معيّن، فيتلقى plant1/# جميع رسائل الموقع 1. يعمل الرمزان في الاشتراكات فقط؛ أما الناشر فيحدّد دائمًا موضوعًا بعينه.

لا ينظر الوسيط داخل الرسالة. فالحمولة مجرد بايتات: رقم بسيط، أو كائن JSON مثل {"temperature": 4.2, "battery": 87}، أو صيغة ثنائية. ويجب أن يعرف كل مشترك كيف يقرأها، وهي المشكلة التي يعالجها Sparkplug في الأنظمة الصناعية.

هناك ميزتان أخريان للوسيط تؤثران في سلوك النظام. عند نشر رسالة مع علامة retain، يحتفظ بها الوسيط بوصفها الرسالة المحفوظة لذلك الموضوع، بواقع رسالة واحدة لكل موضوع، ويرسلها فورًا إلى كل مشترك جديد. وهكذا تُظهر لوحة معلومات فُتحت للتو الوضع الحالي لصمام، دون انتظار التحديث التالي. وتسمح الجلسة المستمرة للوسيط بتذكّر اشتراكات العميل أثناء انقطاعه، ووضع رسائل QoS 1 وQoS 2 في قائمة انتظار حتى يعاود الاتصال. أما إدراج رسائل QoS 0 أيضًا فيعتمد على الوسيط.

يمكنك تشغيل وسيط بنفسك أو استخدام وسيط يديره طرف آخر، ويعمل توصيل أجهزة MQTT بمنصة Kilo في الحالتين. مع Cloud MQTT، تجهّز Kilo وسيطًا بعنوان اتصال وبيانات اعتماد خاصة بكل موصّل، ولا يقبل سوى اتصالات MQTTS المشفّرة على المنفذ 1884. ومع External MQTT، تتصل Kilo بوسيط تشغّله بالفعل، مثل Mosquitto أو HiveMQ أو AWS IoT Core. وفي الحالتين تحدّد كيف تُنسب كل رسالة إلى جهازها: عبر نمط الموضوع أو معرّف جهاز داخل حمولة JSON.

ما هو عميل MQTT؟

عميل MQTT هو أي عنصر يتصل بالوسيط: مستشعر أو بوابة أو تطبيق هاتف أو برنامج يكتب في قاعدة بيانات أو منصة سحابية. وباستثناء الوسيط نفسه، لا يفرض البروتوكول أدوارًا منفصلة. يستطيع كل عميل النشر أو الاشتراك أو القيام بالأمرين.

عند الاتصال، يرسل العميل معرّفًا يجب أن يكون فريدًا على ذلك الوسيط. وإذا وصل اتصال ثانٍ بالمعرّف نفسه، يغلق الوسيط الاتصال الأول، وهذا سبب شائع لانقطاع جهازين بصورة متبادلة ومتكررة. ويمكن للعميل أيضًا إرسال اسم مستخدم وكلمة مرور أو تقديم شهادة، ويحدّد فترة للحفاظ على الاتصال، مثل 60 ثانية. وإذا لم يكن لديه ما يرسله خلال تلك الفترة، يرسل رسالة ping صغيرة ليعرف الوسيط أنه ما زال متصلًا.

تتوفر مكتبات للعملاء، مثل عائلة Eclipse Paho، لمعظم لغات البرمجة تقريبًا وللمتحكمات الدقيقة الصغيرة، ولذلك يمكن لبرنامج Python ولوحة ESP32 استخدام الوسيط نفسه. ولتشخيص المشكلات، يُظهر عميل MQTT مكتبي مشترك في # على وسيط تجريبي كل رسالة فور وصولها.

ما هي مستويات QoS في MQTT؟

جودة الخدمة، أو QoS، إعداد لكل رسالة يحدّد مقدار الجهد الذي يبذله المرسل والمستقبل لإيصالها. ويوفّر MQTT ثلاثة مستويات.

  • QoS 0، مرة واحدة على الأكثر. تُرسل الرسالة مرة واحدة دون تأكيد استلام. وإذا فُقدت في الشبكة، فلن تُستعاد، وهو أمر مقبول للقراءات المتكررة.
  • QoS 1، مرة واحدة على الأقل. يؤكد المستقبل استلام كل رسالة، ويعيد المرسل إرسالها، عادةً بعد استعادة الاتصال، إذا لم يصله التأكيد. لا تضيع الرسالة، لكنها قد تصل مرتين، ولذلك يجب أن يتحمل الطرف المستقبل التكرار.
  • QoS 2، مرة واحدة بالضبط. يضمن تبادل من أربع خطوات تسليم الرسالة مرة واحدة فقط. وهو الأكثر كلفة من حيث تبادل الرسائل، ويناسب الحالات التي يسبب فيها التكرار ضررًا، مثل احتساب الرسوم لكل حدث.

تُطبّق جودة الخدمة بصورة منفصلة على كل جزء من المسار: من الناشر إلى الوسيط، ومن الوسيط إلى كل مشترك. ويتلقى المشترك الرسالة بالمستوى الأقل من المستويين.

لنأخذ مستشعر خزان ينشر مستوى الامتلاء كل 30 ثانية عبر اتصال خلوي. مع QoS 0، لا يسبب فقدان قراءة عابرة مشكلة، لأن التالية ستصل بعد 30 ثانية. لكن أمر إغلاق صمام مختلف: فقدانه مهم، لذلك يُرسل بمستوى QoS 1، وتتعامل وحدة التحكم مع تكرار أمر «إغلاق» دون أثر إضافي.

ما هي رسالة الوصية في MQTT؟

رسالة الوصية، أو Last Will and Testament التي تُختصر عادةً إلى LWT، رسالة يودعها العميل لدى الوسيط عندما يتصل به. تتضمن موضوعًا وحمولة ومستوى QoS. يحتفظ بها الوسيط، ولا ينشرها إلا إذا اختفى العميل دون إشعار: انقطاع الشبكة أو الكهرباء، أو انتهاء مهلة الحفاظ على الاتصال دون مرور بيانات. وإذا أنهى العميل الاتصال بصورة سليمة، يتخلّص الوسيط من الوصية.

يعمل النمط المعتاد كالتالي. عندما تتصل بوابة، تنشر online بوصفها رسالة محفوظة في plant1/gateway7/status، وتسجّل وصية تنشر offline بوصفها رسالة محفوظة في الموضوع نفسه. بذلك يعرف أي مشترك الحالة الحالية للبوابة، حتى بعد حدوث عطل.

تمنح المواصفة الوسيط مهلة تعادل مرة ونصف فترة الحفاظ على الاتصال قبل أن يعتبر العميل الصامت منقطعًا. لذلك، إذا كانت الفترة 60 ثانية، فقد يستغرق ظهور رسالة الانقطاع نحو 90 ثانية. وتتيح MQTT 5، النسخة الحالية من البروتوكول، تحديد تأخير للوصية حتى لا تُعلن إعادة اتصال سريعة باعتبارها عطلًا.

ما هو MQTT Sparkplug؟

MQTT Sparkplug مواصفة تستكمل القواعد التي يتركها MQTT مفتوحة. فـMQTT لا يحدّد طريقة تسمية الموضوعات أو ترميز الحمولة أو معرفة ما إذا كانت الآلة متصلة. لذلك قد يستخدم مصنّعان MQTT دون أن يفهم أحدهما بيانات الآخر. أنشأت Cirrus Link Solutions مواصفة Sparkplug، وانتقلت عام 2019 إلى مؤسسة Eclipse التي تتولى صيانتها اليوم.

بنية الموضوع ثابتة: spBv1.0/<group>/<message type>/<edge node>/<device>. وتستخدم الحمولات ترميزًا ثنائيًا مضغوطًا قائمًا على Protocol Buffers، مع مقاييس ذات أسماء وأنواع بيانات وطوابع زمنية. وتُتابع الحالة من خلال شهادات ميلاد ووفاة. عند اتصال عقدة طرفية، تنشر رسالة ميلاد تسرد كل مقياس ستبلّغ عنه باسمه ونوعه. وبعد ذلك ترسل القيم المتغيّرة فقط، مما يقلّل حركة البيانات في المواقع الكبيرة. وتُسجّل شهادة وفاة العقدة بوصفها وصية MQTT الخاصة بها؛ فإذا انقطعت، يُخبر الوسيط جميع المشتركين دون أن يضطروا إلى السؤال.

يشير الحرف «B» في Sparkplug B إلى إصدار صيغة الحمولة المستخدم حاليًا. وتجد هذه المواصفة غالبًا في المصانع وأنظمة SCADA، حيث تتشارك معدات من مصنّعين مختلفين وسيطًا واحدًا.

أسئلة شائعة عن MQTT

أي منفذ يستخدمه MQTT؟

يستخدم MQTT غير المشفّر منفذ TCP رقم 1883، ويستخدم MQTT عبر TLS المنفذ 8883. وكلاهما مسجّل لدى IANA لبروتوكول MQTT. ويمكن أيضًا إعداد الوسيط للاستماع على أي منفذ آخر.

هل يستخدم MQTT بروتوكول TCP أم UDP؟

يعمل MQTT القياسي عبر TCP لأنه يعتمد على اتصال موثوق في الاتجاهين يحافظ على ترتيب البيانات. ويمكنه أيضًا العمل عبر WebSockets، مما يتيح لصفحة ويب في المتصفح العمل كعميل MQTT. وهناك نسخة منفصلة اسمها MQTT-SN مخصّصة لـUDP ولشبكات المستشعرات التي لا تنقل TCP.

هل MQTT آمن؟

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

ما الفرق بين MQTT 3.1.1 وMQTT 5؟

أصبح MQTT 3.1.1 معيارًا لدى OASIS عام 2014، ثم نُشر لاحقًا باسم ISO/IEC 20922. وتبعه MQTT 5 عام 2019، وأضاف رموز أسباب في رسائل التأكيد، وانتهاء صلاحية الرسائل والجلسات، واشتراكات مشتركة توزّع رسائل الموضوع على عدة عملاء، وخصائص للمستخدم وأسماء بديلة للموضوعات. يدعم كثير من الوسطاء الإصدارين، ويختار كل عميل إصداره عند الاتصال.

أنشئ موصّل Cloud MQTT في حساب Kilo مجاني، وانشر قراءة JSON عبر TLS من أي عميل MQTT إلى عنوان الاتصال الذي يقدّمه، ثم سجّل جهازًا لذلك الموضوع. تعرض علامة التبويب Mapping في الجهاز كل الحقول التي أرسلها مع قيمها الحالية، وتُحوّل عناصر JSON المتداخلة إلى مفاتيح مثل sensor.temperature، وتختار منها ما يصبح مقاييس. يترك جهاز اختبار واحد مساحة لأربعة أجهزة أخرى ضمن الخطة المجانية، بعد التأكد من أن الجهاز الأول يرسل بياناته كما ينبغي.