Bagaimana mesin berkomunikasi - protokol MQTT


Dalam artikel sebelumnya, kami melihat protokol Modbus , yang merupakan standar industri de facto untuk interaksi M2M . Dikembangkan kembali pada tahun 1979, ia memiliki sejumlah kelemahan signifikan yang diselesaikan MQTT.

Protokol MQTT cukup muda (hanya standar pada tahun 2016), tetapi telah berhasil digunakan secara luas di industri dan IoT. Itu dirancang khusus untuk menjadi sekompak mungkin, untuk saluran internet yang tidak stabil dan perangkat berdaya rendah, dan memungkinkan Anda untuk menjamin pengiriman pesan jika terjadi kehilangan dan terputusnya paket.

Fitur Utama dari Protokol MQTT:

  • Ringkas dan ringan - overhead transfer data minimal untuk menghemat lalu lintas.
  • Resistansi terhadap kerugian - pengiriman yang terjamin dalam kondisi koneksi jaringan yang tidak stabil.
  • Asynchronous - memungkinkan Anda untuk melayani sejumlah besar perangkat, dan tidak bergantung pada penundaan jaringan.
  • Dukungan QoS - kemampuan untuk mengontrol prioritas pesan dan menjamin pengiriman pesan kepada penerima.
  • Konfigurasi dinamis - tidak memerlukan koordinasi bidang dan format data sebelumnya, dapat dikonfigurasi dengan cepat.
  • Bekerja untuk NAT - klien dapat berada di belakang NAT, hanya server (broker) yang harus memiliki IP asli. Memungkinkan Anda melakukannya tanpa VPN dan penerusan porta.
  • Pengalamatan nyaman - bidang data memiliki nama teks yang dapat dimengerti oleh manusia. Tidak perlu mengingat alamat digital dan bit offset.

Dalam artikel ini, kita akan membandingkan MQTT dan Modbus, menganalisis struktur protokol, konsep dasar, dan mencoba menggunakan broker cloud MQTT sebagai contoh dalam koneksi Internet yang tidak stabil.

Sejarah Protokol MQTT


MQTT dikembangkan oleh IBM pada tahun 1999, dan pada awalnya digunakan secara internal untuk solusinya.

Pada bulan November 2011, IBM dan Eurotech mengumumkan partisipasi mereka dalam kelompok kerja Eclipse M2M dan transfer kode MQTT ke proyek Eclipse Paho.

Pada 2013, konsorsium OASIS (Organisasi untuk Peningkatan Standar Informasi Terstruktur) memulai proses standarisasi protokol MQTT. Hingga saat ini, spesifikasi protokol telah diterbitkan di bawah lisensi gratis, dan perusahaan seperti Eurotech (sebelumnya dikenal sebagai Arcom) sudah menggunakan protokol dalam produk mereka.

Pada Oktober 2014, OASIS menerbitkan standar protokol MQTT resmi pertama.

Pada 2016, protokol ini distandarisasi oleh Organisasi Internasional untuk Standardisasi ISO dan menerima nomor ISO / IEC 20922.

Sejak 2014, minat pada protokol mulai tumbuh pesat dan, dilihat dari jadwal Google Trends, hari ini melebihi minat di Modbus.


Benchmark Google Trends

Konsep dasar


MQTT memiliki arsitektur client-server. Pesan berlangsung melalui server pusat yang disebut broker. Dalam kondisi normal, klien tidak dapat berkomunikasi secara langsung satu sama lain, dan semua pertukaran data terjadi melalui broker.

Klien dapat bertindak sebagai penyedia data (Penerbit) dan sebagai penerima data (Pelanggan). Dalam terjemahan Rusia, istilah-istilah ini sering diterjemahkan sebagai penerbit dan pelanggan, tetapi untuk menghindari kebingungan, kami hanya akan menggunakan terminologi aslinya.


Dalam protokol MQTT, klien berkomunikasi satu sama lain melalui simpul pusat

Pada tingkat aplikasi, protokol berjalan di atas TCP / IP dan dapat dengan mudah menghubungkan objek jarak jauh langsung melalui Internet, tanpa perlu terowongan VPN. Cukup bagi broker untuk memiliki alamat IP asli dan semua klien dapat terhubung dengannya. Dalam hal ini, klien dapat ditempatkan di belakang NAT. Karena klien memulai koneksi dalam protokol MQTT, port forwarding tidak diperlukan untuk membuat koneksi, sedangkan di Modbus / TCP server memulai koneksi (master), yang memerlukan akses jaringan langsung.

Port broker MQTT standar untuk koneksi TCP yang masuk adalah 1883 . Saat menggunakan koneksi SSL aman, port 8883 digunakan .

Pialang


Pialang adalah pusat MQTT pusat untuk interaksi pelanggan. Pertukaran data antar klien hanya terjadi melalui broker. Broker dapat berupa perangkat lunak server atau pengontrol. Tugasnya termasuk menerima data dari pelanggan, memproses dan menyimpan data, mengirimkan data ke pelanggan, dan memantau pengiriman pesan.

Penerbit / Pelanggan


Untuk memahami perbedaan antara Penerbit dan Pelanggan, mari kita ambil contoh sederhana: sensor kelembaban mengukur kelembaban di suatu ruangan, dan jika turun di bawah tingkat tertentu, humidifier menyala.

Dalam hal ini, sensor kelembaban bertindak sebagai Penerbit : tugasnya adalah hanya mempublikasikan data ke broker. Humidifier bertindak sebagai Pelanggan : berlangganan pembaruan data kelembaban dan menerima data saat ini dari broker, sementara humidifier dapat memutuskan pada titik mana untuk mengaktifkan pelembapan.

Dalam skema ini, klien MQTT, yaitu sensor dan pelembab udara, tidak mengetahui keberadaan satu sama lain, dan tidak berinteraksi secara langsung. Pialang dapat menerima data dari berbagai sumber, memanipulasi mereka, misalnya, menghitung nilai rata-rata dari beberapa sensor, dan mengembalikan data yang diproses ke pelanggan.


Penerbit mengirimkan data ke broker, Pelanggan berlangganan pembaruan data ini

Pada saat yang sama, protokol sinkronisasi MQTT menyatakan bahwa sensor dan pelembab dapat online pada waktu yang berbeda, kehilangan paket, dan tidak dapat diakses. Broker akan mengurus penyimpanan data terakhir yang diterima dari sensor dalam memori dan memastikan pengirimannya ke humidifier.

Topik


MQTT menggunakan topik untuk mengidentifikasi entitas, dalam terjemahan Rusia mereka juga disebut saluran. Topik terdiri dari karakter UTF8, dan memiliki struktur struktur pohon yang mirip dengan sistem file UNIX. Ini adalah mekanisme yang mudah untuk penamaan entitas dalam bentuk yang dapat dibaca manusia.

Contoh topik di MQTT

#     home/kitchen/temperature #     home/sleeping-room/temperature #     home/outdoor/light 

Pendekatan ini memungkinkan Anda untuk melihat secara visual data apa yang dikirimkan, dan akan lebih mudah untuk mengembangkan dan men-debug kode tanpa harus mengingat alamat digital dari penempatan data, seperti yang dilakukan di Modbus.

Topik juga menyertakan sintaksis wildcard, yang biasa bagi mereka yang telah bekerja dengan sistem file UNIX. Wildcard dapat berupa level tunggal dan multi level.

Wildcard satu tingkat ditandai dengan tanda + .

Misalnya, untuk menerima data dari sensor suhu di semua kamar di rumah, pelanggan harus berlangganan ke topik seperti itu:

 home/+/temperature 

Akibatnya, ia akan berlangganan untuk menerima data dari sensor tersebut:

 home/kitchen/temperature home/sleeping-room/temperature home/living-room/temperature home/outdoor/temperature 

Wildcard multi-level ditandai dengan simbol " # ".
Contoh memperoleh data dari semua sensor di semua kamar di rumah:

 home/# 

Berlangganan topik semacam itu akan memungkinkan Anda menerima data dari sensor tersebut:

 home/kitchen/temperature home/kitchen/humidity home/kitchen/light home/sleeping-room/temperature home/sleeping-room/humidity home/sleeping-room/light .... 

Identifikasi pelanggan


Untuk kontrol akses, MQTT menyediakan otentikasi klien, tidak seperti protokol Modbus, yang tidak memiliki fungsi seperti itu. Bidang-bidang berikut digunakan untuk kontrol akses:

ClientId - (bidang wajib diisi) pengidentifikasi unik klien. Harus unik untuk setiap pelanggan. Versi MQTT 3.1.1 standar saat ini memungkinkan Anda untuk menggunakan bidang ClientId kosong jika Anda tidak perlu menyimpan status koneksi.

Nama pengguna - login (bidang opsional) untuk otentikasi, dalam format UTF-8. Mungkin tidak unik. Misalnya, sekelompok klien dapat masuk dengan nama pengguna / kata sandi yang sama.

Kata sandi - (bidang opsional) hanya dapat dikirim bersama dengan bidang Nama Pengguna, sementara Nama Pengguna dapat dikirim tanpa bidang Kata Sandi. Maksimal 65535 byte. Penting untuk mengetahui bahwa nama dan kata sandi ditransmisikan secara jelas, oleh karena itu, jika data ditransmisikan melalui jaringan publik, Anda harus menggunakan SSL untuk mengenkripsi koneksi.

Struktur paket


Seperti disebutkan di atas, dalam protokol MQTT, klien selalu melakukan koneksi, terlepas dari apakah mereka penerima (Pelanggan) atau pemasok (Penerbit) data. Kami akan menganalisis paket dengan koneksi yang disadap menggunakan program Wireshark.


Paket MQTT ditransmisikan melalui saluran yang tidak dienkripsi

Header TCP menunjukkan bahwa paket itu dikirim pada port 1883, yaitu, enkripsi tidak digunakan, yang berarti bahwa semua data tersedia dalam bentuk yang jelas, termasuk login dan kata sandi.

Berita utama


Jenis pesan adalah Connect (perintah 0x0001), membuat koneksi dengan broker. Tim utama: Hubungkan, Putuskan Koneksi, Publikasikan, Berlangganan, Berhenti Berlangganan. Ada juga perintah pengakuan, tetap hidup, dll.

Tandai DUP - berarti pesan dikirim ulang, hanya digunakan dalam jenis pesan PUBLISH, SUBSCRIBE, UNSUBSCRIBE, PUBREL, untuk kasus-kasus ketika pialang tidak menerima konfirmasi tanda terima pesan sebelumnya.
Level QoS - bendera Kualitas Layanan. Kami akan membahas topik ini lebih terinci nanti.
Retain - data yang diterbitkan dengan bendera retain disimpan di broker. Setelah berlangganan ke topik ini, broker akan segera mengirim pesan dengan bendera ini. Hanya digunakan dalam pesan tipe Publikasikan.

Penggunaan praktis




Sekarang, setelah memahami teori ini, mari kita coba bekerja sama dengan MQTT dalam praktiknya. Untuk ini, kami akan menggunakan program Mosquitto terbuka, yang dapat bekerja baik dalam mode klien dan dalam mode server (broker). Ini bekerja pada Windows, macOS, Linux. Program ini sangat nyaman untuk debugging dan mempelajari protokol MQTT, sementara itu juga banyak digunakan dalam operasi industri. Kami akan menggunakannya sebagai klien untuk mengirim dan menerima data dari broker cloud jarak jauh.

Banyak penyedia cloud menyediakan layanan broker MQTT, seperti Microsoft Azure IoT Hub , Amazon AWS IoT , dan lainnya. Dalam contoh ini, kami akan menggunakan layanan Cloudmqtt.com, karena ia memiliki pendaftaran paling sederhana, dan tarif gratis sudah cukup untuk pelatihan.

Setelah pendaftaran, detail untuk menghubungkan ke broker tersedia di akun Anda. Karena kami terhubung ke server melalui jaringan Internet publik, masuk akal untuk menggunakan port SSL untuk mengenkripsi lalu lintas.


Rincian akses pialang MQTT di akun pribadi penyedia cloud

Fleksibilitas protokol MQTT memungkinkan klien untuk mentransfer data yang sebelumnya tidak ditentukan pada broker. Artinya, tidak perlu membuat pra-topik yang diperlukan di mana Penerbit dapat menulis data. Dengan menggunakan data yang diterima dari akun pribadi Anda, kami akan mencoba menyusun permintaan untuk menerbitkan data secara manual ke topik habr / test / acak dan membaca darinya.

mosquitto_sub - utilitas klien pelanggan
mosquitto_pub - utilitas klien penerbit

Pertama, terhubung ke broker sebagai pelanggan, dan berlangganan untuk menerima data dari topik
habr / test / acak .

 mosquitto_sub -d --capath /etc/ssl/certs/ --url mqtts://hwjspxxt:7oYugN7Fa5Aa@postman.cloudmqtt.com:27529/habr/test/random Client mosq/zEPZz0glUiR4aEipZA sending CONNECT Client mosq/zEPZz0glUiR4aEipZA received CONNACK (0) Client mosq/zEPZz0glUiR4aEipZA sending SUBSCRIBE (Mid: 1, Topic: habr/test/random, QoS: 0, Options: 0x00) Client mosq/zEPZz0glUiR4aEipZA received SUBACK 

Dapat dilihat bahwa koneksi berhasil, dan kami berlangganan ke topik habr / test / random , dan sekarang kami sedang menunggu data dalam topik ini dari broker.
Karena koneksi SSL digunakan, untuk memverifikasi sertifikat, Anda harus menentukan jalur di mana program akan mencari sertifikat enkripsi root. Karena layanan dalam contoh kami menggunakan sertifikat yang dikeluarkan oleh otoritas sertifikasi tepercaya, kami menunjukkan jalur ke penyimpanan sistem untuk sertifikat root: --capath / etc / ssl / certs /

Dalam hal sertifikat yang ditandatangani sendiri, Anda harus menentukan jalur ke CA yang diinginkan. Penting juga untuk mempertimbangkan perbedaan dalam format URI untuk koneksi SSL - mqtt s : //, dan koneksi non-terenkripsi - mqtt: //. Jika terjadi kesalahan verifikasi sertifikat, program berakhir tanpa pesan kesalahan. Untuk keluaran yang lebih terperinci, Anda dapat menggunakan sakelar --debug
Sekarang mari kita coba mempublikasikan data dalam topik tanpa mengganggu program pertama.

 mosquitto_pub -d --capath /etc/ssl/certs/ --url mqtt://hwjspxxt:7oYugN7Fa5Aa@postman.cloudmqtt.com:27529/habr/test/random -m " !" Client mosq/sWjh9gf8DRASrRZjk6 sending CONNECT Client mosq/sWjh9gf8DRASrRZjk6 received CONNACK (0) Client mosq/sWjh9gf8DRASrRZjk6 sending PUBLISH (d0, q0, r0, m1, 'habr/test/random', ... (22 bytes)) Client mosq/sWjh9gf8DRASrRZjk6 sending DISCONNECT 

Dapat dilihat bahwa data berhasil diterima oleh server dan dipublikasikan dalam topik yang diinginkan. Pada saat yang sama, di jendela pertama di mana program mosquitto_sub berjalan, kita melihat bagaimana pesan itu diterima, bahkan Unicode berfungsi, pesannya dalam bahasa Rusia.

 Client mosq/zEPZz0glUiR4aEipZA received PUBLISH (d0, q0, r0, m0, 'habr/test/random', ... (22 bytes))  ! 

QoS dan jaminan pengiriman


Namun, mengirim pesan secara real time tidak akan mengejutkan siapa pun, karena hal yang sama dapat dilakukan bahkan dengan utilitas dangkal nc . Oleh karena itu, kami akan mencoba mensimulasikan koneksi yang tidak stabil antara pelanggan dan pengirim. Bayangkan kedua klien bekerja melalui GPRS, dengan paket yang sangat besar, dan bahkan koneksi TCP yang sukses jarang terjadi, dan Anda perlu memastikan bahwa pelanggan dijamin untuk menerima pesan pengirim. Dalam hal ini, opsi QoS datang untuk menyelamatkan.

Secara default, bendera QoS diatur ke 0 untuk pesan, yang berarti β€œApi dan lupakan”: Penerbit mempublikasikan pesan pada broker, tetapi tidak mengharuskan pesan tersebut dijamin untuk dikirim ke pelanggan. Ini cocok untuk data yang kehilangannya tidak kritis, misalnya, untuk pengukuran kelembaban atau suhu secara teratur.

QoS 1: Setidaknya sekali - setidaknya satu . Bendera ini berarti bahwa sampai Penerbit menerima konfirmasi pengiriman kepada pelanggan, publikasi ini akan dikirim ke broker, dan kemudian ke pelanggan. Dengan demikian, pelanggan harus menerima pesan ini setidaknya sekali.

QoS 2: Persis sekali - dijamin . Bendera QoS, yang memberikan jaminan tertinggi pengiriman pesan melalui penggunaan prosedur tambahan untuk konfirmasi dan penyelesaian publikasi (PUBREC, PUBREL, PUBCOMP). Berlaku untuk situasi di mana perlu untuk mengecualikan kehilangan dan duplikasi data dari sensor. Misalnya, ketika alarm dipicu dari pesan yang diterima, panggilan darurat dilakukan.

Untuk mensimulasikan komunikasi yang buruk, matikan kedua klien dan cobalah untuk mengirim pesan dengan prioritas QoS tertinggi, dan juga tambahkan opsi Retain sehingga pesan yang terkirim disimpan di broker.

 mosquitto_pub --retain --qos 2 -d --capath /etc/ssl/certs/ --url mqtt://hwjspxxt:7oYugN7Fa5Aa@postman.cloudmqtt.com:27529/habr/test/random -m "  !" Client mosq/Xwhua3GAyyY9mMd05V sending CONNECT Client mosq/Xwhua3GAyyY9mMd05V received CONNACK (0) Client mosq/Xwhua3GAyyY9mMd05V sending PUBLISH (d0, q2, r1, m1, 'habr/test/random', ... (37 bytes)) Client mosq/Xwhua3GAyyY9mMd05V received PUBREC (Mid: 1) Client mosq/Xwhua3GAyyY9mMd05V sending PUBREL (m1) Client mosq/Xwhua3GAyyY9mMd05V received PUBCOMP (Mid: 1, RC:0) Client mosq/Xwhua3GAyyY9mMd05V sending DISCONNECT 

Sekarang, setelah beberapa waktu, penerima kami akhirnya dapat membuat koneksi ke Internet dan terhubung ke broker:

 mosquitto_sub -d --capath /etc/ssl/certs/ -d --url mqtts://hwjspxxt:7oYugN7Fa5Aa@postman.cloudmqtt.com:27529/habr/test/random Client mosq/VAzcLVMB1MiWhYxoJS sending CONNECT Client mosq/VAzcLVMB1MiWhYxoJS received CONNACK (0) Client mosq/VAzcLVMB1MiWhYxoJS sending SUBSCRIBE (Mid: 1, Topic: habr/test/random, QoS: 0, Options: 0x00) Client mosq/VAzcLVMB1MiWhYxoJS received SUBACK Subscribed (mid: 1): 0 Client mosq/r6UwPnDvx8aNInpPF6 received PUBLISH (d0, q0, r1, m0, 'habr/test/random', ... (37 bytes))   ! 

Kesimpulan


MQTT adalah protokol modern dan canggih, tanpa banyak kelemahan dari pendahulunya. Fleksibilitasnya memungkinkan Anda untuk menambah perangkat klien tanpa membuat broker, yang secara signifikan menghemat waktu. Ambang entri untuk memahami dan mengkonfigurasi protokol sangat rendah, dan keberadaan perpustakaan untuk banyak bahasa pemrograman memungkinkan Anda memilih tumpukan teknologi untuk pengembangan. Jaminan pengiriman pesan secara signifikan membedakan MQTT dari pendahulunya, dan memungkinkan Anda untuk tidak membuang waktu mengembangkan mekanisme kontrol integritas Anda sendiri di tingkat jaringan.

Source: https://habr.com/ru/post/id452904/


All Articles