在《物聯網核心協議—消息推送技術演進》一文中已向讀者介紹了多種消息推送技術的情況,包括HTTP單向通信、Ajax輪詢、Websocket、MQTT、CoAP等,其中MQTT協議為IBM制定並力推,其具有開放、簡單、輕量級以及易於實現的特點使得其即便在資源受限的環境中也能得到很好的使用,比如運行在資源緊缺型的嵌入式系統中或網絡帶寬非常昂貴的環境中,除此之外,它也被廣泛用於遙感勘測、智能家居、能源監測和醫療應用程序等各個領域,是物聯網的重要組成部分,將來可能會成為物聯網的事實標准。
本篇文章將幫助讀者認識MQTT協議以及在Linux環境下部署MQTT的開源實現Mosquitto進行體驗驗證,在后續文章中將展開對其源碼框架的分析,為構建物聯網平台做好鋪墊。
一、MQTT協議分析
1.1、MQTT協議簡介
MQTT(MessageQueueing Telemetry Transport Protocol)的全稱是消息隊列遙感傳輸協議的縮寫,是由IBM公司推出的一種基於輕量級代理的發布/訂閱模式的消息傳輸協議,運行在TCP協議棧之上,為其提供有序、可靠、雙向連接的網絡連接保證。由於其開放、簡單和易於實現所以能夠應用在資源受限的環境中,對於M2M和物聯網應用程序來說是一個相當不錯的選擇。
1.2、發布者/訂閱者
MQTT采用代理的發布/訂閱模式實現了發布者和訂閱者的解耦(decouple),因此,在MQTT協議中有三種角色:代理服務器、發布者客戶端以及訂閱者客戶端,其中發布者和訂閱者互不干擾,也就是說發布者和訂閱者互不知道對方的存在,它們只知道代理服務器,代理服務器負責將來自發布者的消息進行存儲處理並將這些消息發送到正確的訂閱者中去。這種解耦體現在以下3個方面上:
·空間解耦:發布者和訂閱者不必知道對方的存在,例如對方的IP地址或者端口;
·時間解耦:發布者和訂閱者不必同時建立連接;
·同步解耦:發布者和訂閱者在發布消息或接收消息的時候不需要同步;
1.3、MQTT的消息類型
MQTT的三種角色通過14種不同的消息類型進行交互:
1.CONNECT控制報文用於客戶端請求與服務器建立連接,應用層的連接而不是TCP/IP連接,CONNECT控制報文的發送在TCP/IP建立連接后;
2.CONNACK控制報文用於服務器向請求連接的客戶端回發連接確認;
3.PUBLISH控制報文用於發布指定主題名的應用信息;
4.PUBACK/PUBREC/PUBREL/PUBCOMP控制報文用於針對不同服務質量的應用信息的回應;
5.SUBSCRIBE控制報文用於訂閱者向服務器發送一個主題過濾器列表,用於表示客戶端想要訂閱的主題;
6.SUBACK控制報文用於SUBSCRIBE控制報文的響應;
7.UNSUBSCRIBE控制報文用於向服務器發送一個主題過濾器列表,用於表示客戶端想要取消訂閱的主題;
8.UNSUBACK控制報文用於UNSUBSCRIBE控制報文的響應;
9.PINGREQ/PINGRESP控制報文作為客戶端和服務器間的心跳包;
10.DISCONNECT控制報文用於客戶端在斷開前告訴服務器其將斷開連接;
1.4、主題(topic)
使用主題是服務器為每一個客戶端管理應用信息所采用的一種方式,一個主題名可以由多個主題層級(topic level)組成,每一層通過’/’斜杠分隔開,當客戶端指定的主題過濾器包含通配符時,即客戶端想一次訂閱多個具有類似結構的主題時,主題層級分隔符就很有用了。
主題通配符只可用在主題過濾器中,在發布應用消息時的主題名不允許包含通配符,主題通配符有兩種:
單層通配符:’+’,它會匹配某一個主題層級中的所有主題;
多層通配符:’#’,它會匹配多個主題主題層級的主題;
例如:如果客戶端訂閱時的主題過濾器為”grade/subject/math/#”,它會收到使用下列主題名發布的消息:
“grade/subject/math”
“grade/subject/math/student1”
“grade/subject/math/student1/lastterm”
1.5、服務質量等級(QosLevels)
MQTT提供三種Qos的消息傳遞質量:
a.最多一次(Atmost once delivery):QoS=0,協議對此等級應用信息不要求回應確認,也沒有重發機制,這類信息可能會發生消息丟失或重復,取決於TCP/IP提供的盡最大努力交互的數據包服務。
b.最少一次(Atleast once delivery):QoS=1,確保信息到達,但消息重復可能發生,發送者如果在指定時間內沒有收到PUBACK控制報文,應用信息會被重新發送,且控制報文中DUP標志位置1。
c.僅僅一次(Exactlyonce delivery):QoS=2,最高級別的服務質量,消息丟失和重復都是不可接受的。
1.6、支持MQTT協議的服務器和客戶端
當前流行的開源代理服務器(MQTT Broker)的實現有:mosquitto, HiveMQ, Apache ActiveMQ, RabbitMQ, mosca等,MQTT客戶端也有不同操作系統和編程語言下的實現,流行的客戶端庫(MQTT ClientLibraries)有:Eclipse Paho(支持C,C++, Java, JavaScript, Python, Go, C#), M2MQTT(C#), Fusesource MQTTClient(Java), MQTT.js(javascript), libmosquitto(c/c++)等等,通過以上庫而開發出的MQTT客戶端應用程序有:mosquitto_pub/mosquitto_sub(可運行於Linux, Windows, MacOSX操作系統), HiveMQWebsocket Client(Web browser), MyMQTT(Android), MQTTLens(Google Chrome)等等。
二、Mosquitto部署驗證
2.1、Ubuntu下安裝Mosquitto
1.源碼包下載:http://mosquitto.org/files/source/
版本:mosquitto-1.4.tar.gz
解壓:tar -zxvf mosquitto-1.4.tar.gz
進入目錄:cd mosquitto-1.4
2.編譯安裝
打開配置文件,去掉暫且不需要的功能:
vi config.mk
如:WITH_TLS,WITH_TLS_PSK, WITH_SRV, WITH_WEBSOCKETS, WITH_SOCKS, WITH_UUID等
保存退出:wq
安裝mosquitto
make
make install
2.2、啟動mosquitto服務器
mosquitto默認以mosquitto用戶啟動,所以首先創建mosquitto用戶:
adduser mosquitto
啟動代理服務器:mosquitto -c/etc/mosquitto/mosquitto.conf.example
在啟動服務器過程中有可能遇到以下錯誤:找不到libmosquitto.so.1文件,解決方法是添加鏈接庫路徑:
vi/etc/ld.so.conf.d/liblocal.conf
/usr/local/lib64
/usr/local/lib
退出文件后刷新:ldconfig
重新執行:mosquitto -c /etc/mosquitto/mosquitto.conf.example
2.3、啟動訂閱者客戶端mosquitto_sub,訂閱test主題
mosquitto_sub客戶端應用程序位於/mosquitto-1.4/client目錄下,執行./mosquitto_sub-t test, -t表示主題過濾器屬性,后面帶指定的主題過濾器。
2.4、啟動發布者客戶端mosquitto_pub,並且多次發布主題信息
./mosquitto_pub-t test -l
其中-t表示發布的主題名,主題名中不允許包含通配符,-l是指通過標准輸入的方式輸入將要發布的應用信息,更多的屬性可通過:./mosquiito_pub --help了解,也可通過官網了解:
http://mosquitto.org/man/mosquitto_pub-1.html。
發布者發布應用信息:
2.5、發布者通過鍵入”Ctrl+D”向服務器發送DISCONNECT控制報文,然后正常退出
如果通過”Ctrl+C”終止客戶端程序(異常網絡斷開),服務器將提示:Scoket error
本篇文章初步講述了MQTT協議及以其中的一種實現為例進行部署和體驗,協議的詳細具體內容如控制報文格式等,讀者可自行到官網下載文檔查閱,也可以關注嵌入式企鵝圈來獲取共享資源。