官方協議有句如下的話來形容MQTT的設計思想:
“It is designed for connections with remote locations where a "small code footprint" is required or the network bandwidth is limited.”
MQTT:開源、可靠、輕巧、簡單,MQTT的傳輸格式非常精小,最小的數據包只有2個比特,且無應用消息頭。
MQTT可以保證消息的可 靠性,它包括三種不同的服務質量(最多只傳一次、最少被傳一次、一次且只傳一次),如果客戶端意外掉線,可以使用“遺願”發布一條消息,同時支持持久訂 閱。MQTT在物聯網以及移動應用中的優勢有:
- 可靠傳輸。MQTT可以保證消息可靠安全的傳輸,並可以與企業應用簡易集成。
- 消息推送。支持消息實時通知、豐富的推送內容、靈活的Pub-Sub以及消息存儲和過濾。
- 低帶寬、低耗能、低成本。占用移動應用程序帶寬小,並且帶寬利用率高,耗電量較少。
因此MQTT被廣泛應用於物聯網。
源碼位置,可下載時間最新的CODE:http://mosquitto.org/files/source/
虛擬機搭建MQTT環境,進行MQTT初體驗
參考:http://blog.csdn.net/xukai871105/article/details/39252653
安裝:
安裝mosquitto時候出現這樣的問題
1.mosquitto_internal.h:51:20: error: ares.h: No such file or directory
其實是因為它新加的功能的原因。打開config.mk文件。
吧WITH_SRV:=yes 改成WITH_SRV:=no 就可以編譯了
或者sudo apt-get install libc-ares-dev
2,
找不到libmosquitto.so.1
error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
【解決方法】——修改libmosquitto.so位置
# 創建鏈接
sudo ln -s /usr/local/lib/libmosquitto.so.1 /usr/lib/libmosquitto.so.1
# 更新動態鏈接庫
sudo ldconfig
簡單測試
一個完整的MQTT示例包括一個代理器,一個發布者和一個訂閱者。測試分為以下幾個步驟:
【1】啟動服務mosquitto。
【2】訂閱者通過mosquitto_sub訂閱指定主題的消息。
【3】發布者通過mosquitto_pub發布指定主題的消息。
【4】代理服務器把該主題的消息推送到訂閱者。
【測試說明】
測試環境:ubuntu 14.04 虛擬機
在本例中,
發布者、代理和訂閱者均為localhsot,但是在實際的情況下三種並不是同一個設備,在mosquitto中可通過-h(--host)設置主機名稱(hostname)。為了實現這個簡單的測試案例,需要在linux中打開三個控制台,分別代表代理服務器、發布者和訂閱者。
啟動代理服務
mosquitto -v
【-v】打印更多的調試信息
訂閱主題
mosquitto_sub -v -t SmartAudio_zhangling
【-t】指定主題,此處為SmartAudio_zhangling
【-v】打印更多的調試信息
root@ubuntu:/opt/mqtt/mosquitto-1.4.10/src# ./mosquitto -c ../mosquitto.conf
1474336624: mosquitto version 1.4.10 (build date 2016-09-19 18:55:57-0700) starting
1474336624: Config loaded from ../mosquitto.conf.
1474336624: Opening ipv4 listen socket on port 1883.
1474336624: Opening ipv6 listen socket on port 1883.
1474336624: Error: Invalid user 'mosquitto'.
root@ubuntu:/opt/mqtt/mosquitto-1.4.10/src#
解決方法:
1.修改配置文件:mosquitto.conf ,增加登錄的用戶
2.執行 adduser mosquitto
發布消息
mosquitto_pub -t SmartAudio_zhangling -m 12
【-t】指定主題
【-m】指定消息內容
【-f】 是可以發送文件
通過-f傳遞的文件上限默認是256M。邏輯中有對文件大小的判斷,超過256M的文件則不傳。不知道這里如果吧這個值修改更大,會不會產生影響,筆者沒有嘗試,因為傳7M的文件都感覺很慢。
(這個問題在MQTT協議介紹中可以得到答案,MQTT文件長度的表示是用1至4個字節來表示,而其表示長度的方式又有特殊的加密方式,按照這種方式,其最大表示的長度為256M)
如果不是在同一個設備,可通過-h指定代理的IP。
(
另外還有一個mosquitto_passwd,用於管理密碼,應該是關閉SSL的原因)
運行結果
當發布者推送消息之后,訂閱者獲得以下內容
=======================mosquitto部分,嵌入音箱端及手機微信端,可實現廣域網內手機微信對音箱的控制=================================
服務器部分
mosquitto服務器部分,肖同學負責搭建好。音箱端與手機端pub和sub都是通過服務器進行消息傳遞。IP地址為"120.76.30.18";
音箱部分
進入網絡模式下,則需要開啟一個線程,用來開啟mosquitto subscribe 訂閱一個主體。一個音箱實體對應一個主體。其他客戶端可通過這個主題,來與音箱端實現鏈接。
本項目,定義的主題名字利用音箱的物理地址的唯一性,如SmartAudio_MacAddress。
手機微信部分
而,手機客戶端如何得知音箱端這個主題,方法一,是微信客戶端有提供對應開發包,局域網設備發現,但是這個功能依賴微信端,尚不穩定,最后並沒采用;
方法二:將主題生成二維碼,貼在音箱上。目前采用方法二。
而協議約定客戶端名字,可以是b_MacAddress。
而手機微信部分是客戶端IOS/Android同仁負責,這里不作介紹。
下面主要介紹音箱部分移植mosquitto進行應用開發的內容:
開啟訂閱主題線程
pthread_create(&mosquitto_client_thread_id, NULL,
mosquitto_sub_start, NULL)
mosquitto_sub_start 是利用mosquitto sub的源碼加以修改。
核心內容是,
兩個回調函數的注冊
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
其中my_connect_callback是mosquitto_loop_forever這個一直存在的循環函數在收到服務器傳遞回來CONNACK信息(見_mosquitto_handle_connack),則會被觸發,用來呼叫mosquitto_subscribe完成訂閱。
其中my_message_callback則是用於音箱端應用程序的開發,用來接收手機微信端傳遞過來的內容。與手機客戶端定義交互的協議,用於控制音箱的推歌、上下首切換、音源切換、網絡模式的切換、音量大小的改變等等。
交互的內容采用json包,因此需要進行json包的解析和封裝。
正確完成音箱端的訂閱,
注意設定好:
cfg.port = 1883;
cfg.topics[cfg.topic_count-1] = strdup(deviceName);
cfg.host = strdup(serverIp); //服務器地址
這里初始化了一個屬於音箱端全局的mosq,可用它關聯pub和sub;(pub和sub共用一個全局mosq即可,並不需要分別申請一個mosq)
音箱端部分,需要pub消息給手機微信端。采用mosquitto_pub_start發送消息。這個不同於sub是一個一直存在的線程,pub屬於一次性,消息傳遞完畢即結束。
mosquitto_pub_start 中 全局變量pub_topic ,在mosquitto_sub_start里面有初始化。