基於MQTT協議進行應用開發


官方協議有句如下的話來形容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/

截止到2016年6月,最新的code為:
mosquitto-1.4.9.tar.gz 
 
虛擬機搭建MQTT環境,進行MQTT初體驗
參考:http://blog.csdn.net/xukai871105/article/details/39252653
 
安裝:
# 下載源代碼包 
wget  http://mosquitto.org/files/source/mosquitto-1.4.9.tar.gz
# 解壓
tar zxfv mosquitto-1.4.9.tar.gz
# 進入目錄
cd mosquitto-1.4.5
# 編譯
make
# 安裝
sudo make install
 
 
 
安裝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里面有初始化。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM