記住名字 MQTT,因為它是網絡通信協議類型M2M(機器對機器),聽起來會很不錯。 由於物聯網或IoT(物聯網)的英文縮寫,它正變得非常流行。 另外,它是一個開放協議,具有許多優點。
實際上,它已經成為物聯網的中心支柱之一,因為它在諸如此類傳輸限制的設備上非常出色。 首字母縮寫MQTT來自 消息隊列遙測傳輸是OASIS和ISO(ISO / IEC 20922)的一種開放標準,用於網絡通信,通常在著名的TCP / IP上運行。
網絡協議
很多 通訊協議 它們是允許兩個或多個設備或系統相互通信的規則。 也就是說,它是一種協議,可以通過各種方式以定義的格式傳輸信息,而無論是通過軟件和硬件(或兩者)來實現。
El 標準 協議的定義定義了多種通信特性。 它可以來自同步,語義,語法,數據包格式等規則。 事實是它們不可忽略,因為有了這些協議,我們今天可以使用互聯網和其他通信網絡...
當然,不僅有一個協議,而且還有很多。 例如, 有名的 適用於應用程序層的DNS,FTP,MQTT,HTTP和HTTPS,IMAP,LDAP,NTP,DHCP,SSH,Telnet,SNMP,SMTP等。 在傳輸層中,您可以找到一些像TCP,UDP等著名的東西,以及Internet層的那些東西,例如IPv4或IPv6(這使得最大數量的可用IP和物聯網的到來) ),IPSec等,以及來自鏈路層的其他信息,例如DSL,以太網,WiFi,ARP等。
關於物聯網協議
當然,有特定的通信協議或可以將其應用於 物聯網。 也就是說,考慮到上一節,它們將是一系列已定義的標準,以便兩個或多個IoT設備可以相互通信和理解,並且它們通常是M2M,即機器對機器通信。許多物聯網設備連接並共享來自傳感器或其他來源的信息。
由於物聯網設備數量眾多,因此這些協議必須滿足帶寬,速度等限制之外的要求。 (請注意,許多設備都是嵌入式且價格便宜的),通常在某些設備中會出現這種情況。 我的意思是, 必須是可擴展的,以便在必要時添加更多已連接的設備,而又不影響全局系統。
另外,他們必須有一個 低依賴性 設備之間的耦合,因此,如果卸下設備,則不會產生問題。 當然,與此同時,由於物聯網世界的異構性,人們尋求一種高互操作性,使其可與大量設備和種類繁多的系統配合使用。
其他有用的功能將是易於實現, 安全, 等等。 請記住,物聯網在安全方面帶來了巨大的挑戰。 在某些情況下,當許多連接的設備往往至關重要時,更是如此……例如,未成年人的玩具。
重要概念
也就是說,必須說物聯網解決方案使用集中式服務器來接收來自所有已連接設備的消息,這些消息會發出並分發給正在偵聽的所有已連接物聯網設備。 該服務器是所謂的 路由器或代理。 在某些方面與常規的客戶-服務器關係相去甚遠。
此外, 方法論 在這些用於IoT的通信協議中可以找到:
- 發布訂閱:發布/訂閱是一種消息傳遞模式,其中設備(Sub)通知代理它希望接收消息,而另一台設備(Pub)發布消息供代理分發給其他正在等待它們的設備。
- 遠程RPC:路由器修改程序過程調用是遠程過程執行的另一種模式。 在其中,設備(被調用方)通知代理它將執行某個過程,並且代理將其分發到在其上執行了該過程的另一個設備(調用方)。
現在,要執行這些方法或模式, 消息傳遞基礎結構。 從這個意義上講,可以區分兩個:
- 消息隊列:消息傳遞服務,其中為啟動對代理的訂閱的所有客戶端生成單個消息隊列。 後者將保留消息,直到將它們傳遞給客戶端為止。 如果客戶端或收件人未連接,則將保持連接狀態。 這些類型的服務類似於即時消息應用程序(例如Telegra,WhatsApp,Messenger等)中使用的服務。
- 留言服務:這是代理將消息發送到連接的收件人客戶端的另一項服務,它按消息的類型進行過濾。 如果客戶端或接收設備斷開連接,則消息將丟失(儘管它可能具有某些日誌記錄系統)。
物聯網協議
看完上面的內容後,現在讓我們仔細看一下 物聯網協議 眾所周知。 M2M中最突出的是:
- AMQP(高級消息隊列協議):是Message Queue的PubSub類型協議。 設計具有良好的互操作性並確保可靠性。 特別適用於公司應用,高性能,高延遲網絡,關鍵等。
- WAMP(Web應用程序消息傳遞協議):它是PubSub類型的另一個開放協議,如rRPC,它在WebSockets上運行。
- CoAP(受限應用協議):是專門為低容量應用程序設計的協議。
- TOMP(流文本定向消息協議):非常簡單的協議並實現最大的互操作性。 HTTP用於傳輸文本消息。
- XMPP(可擴展消息傳遞和狀態協議):IoT中用於即時消息傳遞應用程序且基於XML的另一種協議。 Jan此案也未決。
- WMQ(WebSphere消息隊列):IBM開發的協議。 顧名思義,它是Message Queue類型,並面向消息。
- MQTT:(請參閱下一部分)
關於MQTT
El MQTT協議 這是一個Message Queue通信協議,它遵循PubSub模式,並且具有M2M類型,正如我之前已經評論過的那樣。 它被廣泛用於IoT中,並且基於Internet上使用的TCP / IP堆棧。
對於MQTT, 每個連接都保持打開狀態 並在每次必要的通訊中重複使用。 與其他已知協議中發生的事情不同的是,每次通信都需要一個新的連接。
優點
在用於物聯網的M2M通信方面,MQTT協議的優勢非常明顯。 除了上述內容外,該協議還提供:
- 可擴展性,連接越來越多的客戶。
- 客戶端之間的解耦,減少了依賴性。
- 異步性。
- 簡單。
- 輕便,以免消耗過多資源(儘管使用TLS / SSL安全性會提高)。
- 對於依靠電池或24/7全天候工作的設備而言,具有高能效,不需要大帶寬(慢速連接的理想選擇,例如某些無線連接)
- 安全性和質量,以提高通信的可靠性和魯棒性。
歷史
MQTT創建於90年代,其早期版本 1999年的協議。 它是由IBM的Andy Stanford-Clark博士和Cirrus Link(以前是Eurotech)的Arlen Nipper共同創建的。
La 最初的想法 旨在創建一個協議來監控穿越沙漠的管道,該協議具有高效的通信協議(低帶寬消耗),輕便且能耗低的特點。 當時它非常昂貴,但現在它已成為一種便宜且開放的協議。
最初的協議隨著外觀的出現而得到了改進 新版本, 例如OASIS(結構化信息標準組織)規範下的MQTT v3.1(2013)等。 您應該知道,一開始它是專有的IBM協議,但是它將在2010年發布,並且最終成為OASIS的標準...
MQTT連接如何工作
MQTT協議使用 過濾器,用於根據主題或層次結構組織的主題發送給每個客戶端的消息。 這樣,客戶可以發布有關特定主題的消息。 這樣,所有訂閱該主題的客戶端或連接的設備都將通過代理接收消息。
與MQ一樣, 郵件將保留在隊列中 在客戶收到該消息之前,它們不會丟失。
正如我還指出的那樣,已建立連接 通過TCP / IP,服務器或代理將保留已連接客戶端的記錄。 默認情況下,設備將使用通信端口號1883,但是如果您使用SSL / TLS來提高安全性,則也可能會遇到端口8883。
為了使連接成為可能,不僅需要客戶端,服務器和端口。 還有其他 包裹或郵件已發送 進行溝通:
- 建立聯繫:客戶端發送的CONNECT消息/數據包,其中包含所有必要的信息。 該信息包括客戶ID,用戶名,密碼等。 代理或服務器以CONNACK數據包作為響應,該數據包將通知客戶端連接已被接受,拒絕等。
- 發送和接收消息:建立連接後,將PUBLISH包或消息與發送給代理的消息的主題和有效負載一起使用。 另一方面,感興趣的客戶使用SUBSCRIBE和UNSUSCRIBE包分別訂閱或撤消其訂閱。 代理還將分別以SUBACK和UNSUBACK包進行響應,以報告客戶端請求的操作成功。
- 維持連接:為了確保連接保持打開狀態,客戶端可以定期發送PINGREQ數據包,該數據包將與來自服務器的PINGRESP數據包匹配。
- 終端連接:當客戶端斷開連接時,它將發送DISCONNECT數據包以報告該事件。
那些 消息或包裹 我所討論的結構與其他網絡協議的其他數據包具有相同的結構:
- 標頭或固定標頭:是一個固定的部分,佔用2-5個字節。 它包含一個控制代碼,發送的消息類型的ID及其長度。 使用1-4個字節之間的長度來編碼長度,使用每個八位位組的前7位作為長度的數據,並使用附加的連續位來確定組成消息長度的字節不止一個。
- 可變標題:並非總是強制性的,而是可選的。 它僅在某些情況下或特定消息中包含在某些軟件包中。
- 內容或數據:數據包數據實際上是包含要發送的消息的數據。 它的大小可以從幾kB到256 MB不等。
如果您有興趣了解 十六進制對應的代碼 發送的消息類型為:
信息 | 碼 |
---|---|
CONNECT | 0x10 |
康納克 | 0x20 |
發布 | 0x30 |
回送 | 0x40 |
恥骨 | 0x50 |
公開 | 0x60 |
公用事業單位 | 0x70 |
訂閱 | 0x80 |
蘇巴克 | 0x90 |
取消訂閱 | 0xA0 |
取消訂閱 | 0xB0 |
平格雷 | 0xC = |
平RESP | 0xD0 |
斷開 | 0xE0 |
通信的質量和安全性
MQTT消息的另一個重要細節是 服務質量或QoS,以及安全性。 通信系統在發生故障時的魯棒性及其安全性將取決於此。
關於它的質量,可以確定 3個不同級別:
- QoS 0(無確認):該消息僅發送一次,並且在失敗的情況下將不會傳遞。 當它不是關鍵時使用。
- QoS 1(確認):該消息將根據需要發送多次,以確保傳遞給客戶。 缺點是客戶端可能多次收到相同的消息。
- QoS 2(確保)-與上述類似,但保證只能交付一次。 它通常用於需要更高可靠性的更關鍵的系統。
另一方面,至於 MQTT安全性,可以使用各種措施來確保其在這方面的優勢。 正如我之前已經提到的,用戶名和密碼的自動化,就像許多其他協議一樣,可以通過SSL / TLS來確保。 儘管使用這種類型的安全通信時,許多容量或資源不足的IoT設備可能會出現工作量過大的問題...
因此,許多使用MQTT的IoT設備都使用密碼,並且用戶使用 純文本,這可能會使某人嗅探網絡流量以使其變得非常容易。 如果這還不夠,還可以將代理配置為接受匿名連接,這將允許任何用戶建立通信,涉及更大的風險。
在Arduino上使用MQTT
當然可以 在Arduino上使用MQTT協議 和其他開發板,以及Rapsberry Pi等。 為此,您必須為Arduino板提供連接(如果沒有)。 還有圖書館 適用於MQTT的Arduino客戶端 它將幫助您完成這些任務。 該庫兼容:
關於 到使用MQTT的代碼 在某些應用中,事實是它很簡單。 在Fritzing圖片中,您可以看到一塊牙菌斑 Arduino UNO 已添加並通過Arduino以太網連接的連接 DHT22濕度和溫度傳感器,儘管可能還沒有其他...
好的,這樣說,您必須在其中生成的代碼 Arduino IDE 要在Arduino上使用MQTT協議,就這麼簡單:
- 至 發送信息 MQTT
#include <SPI.h> #include <Ethernet.h> #include <PubSubClient.h> #include <DHT.h> #define DHTPIN 2 #define DHTTYPE DHT22 // Direccion MAC del adaptador Ethernet byte mac[] = { 0xCE, 0xAB, 0x0E, 0x3F, 0xFE, 0xD4 }; // IP del servidor (broker) IPAddress mqtt_server(192, 168, 1, 4); // Topic o tema con el que se trabaja const char* topicName = "test"; DHT dht(DHTPIN, DHTTYPE); EthernetClient ethClient; PubSubClient client(ethClient); void setup() { Serial.begin(9600); if (Ethernet.begin(mac) == 0) { Serial.println("Fallo en Ethernet usando DHCP"); } // Puerto 1883 de comunicación client.setServer(mqtt_server, 1883); dht.begin(); } void loop() { if (!client.connected()) { Serial.print("Conectando ...\n"); client.connect("Cliente Arduino"); } else { // Envío de informacion del sensor de temperatura y humedad float temp = dht.readTemperature(); char buffer[10]; dtostrf(temp,0, 0, buffer); client.publish(topicName, buffer); } // Tiempo entre envíos en ms (cada 10 segundos) delay(10000); }
- 至 接收消息 通過MQTT,您只需要盤子 Arduino UNO 並通過Arduino以太網或任何其他元素進行連接。 至於代碼,一個例子是:
#include <SPI.h> #include <Ethernet.h> #include <PubSubClient.h> // Direccion MAC del adaptador Ethernet byte mac[] = { 0xCE, 0xAB, 0x0E, 0x3F, 0xFE, 0xD4 }; // IP del servidor (broker) IPAddress mqtt_server(192, 168, 1, 4); // Topic o tema con el que trabajr const char* topicName = "test"; EthernetClient ethClient; PubSubClient client(ethClient); void callback(char* topic, byte* payload, unsigned int length) { Serial.print("El mensaje ha llegado ["); Serial.print(topic); Serial.print("] "); int i=0; for (i=0;i<length;i++) { Serial.print((char)payload[i]); } Serial.println(); } void setup() { Serial.begin(9600); if (Ethernet.begin(mac) == 0) { Serial.println("Fallo en Ethernet al usar configuración DHCP"); } client.setServer(mqtt_server, 1883); client.setCallback(callback) } void loop() { if (!client.connected()) { Serial.print("Conectando ..."); if (client.connect("rece_arduino")) { Serial.println("conectado"); client.subscribe(topicName); } else { delay(10000); } } // Cliente a la escucha client.loop(); }
有關更多信息,您可以 免費下載 NUESTRO PDF手冊 與Arduino IDE課程一起開始編程。