05--MQTT物聯網協議

一、MQTT的概念

MQTT 協議快速入門 2025:基礎知識和實用教程 | EMQ

1.MQTT(Message Queuing Telemetry Transport)是一種輕量級、基于發布-訂閱模式的消息傳輸協議,適用于資源受限的設備和低帶寬、高延遲或不穩定的網絡環境。它在物聯網應用中廣受歡迎,能夠實現傳感器、執行器和其它設備之間的高效通信。

2.訂閱與發布規則

二、MQTT 代理服務器

三、Mosquitto 代理服務器

Eclipse Mosquitto?也是一款開源的 MQTT Broker,兼容 MQTT 協議的 5.0、3.1.1 和 3.1 版本。Mosquitto 體積小巧,既可以運行在低功耗的單板計算機上,也可以部署在企業級服務器上。它采用 C 語言編寫,可以用 C 庫實現 MQTT 客戶端。它支持 Windows、Mac、Linux 和 Raspberry Pi 等多種平臺,為每個平臺提供了方便安裝的二進制文件。最新版本還增加了一個認證和授權插件 “mosquitto-go-auth”,以及一個用于管理 Mosquitto 實例的 Web 用戶界面。此外,它還提供了一個 PHP 包裝器 “Mosquitto-PHP”,可以方便地在 PHP 中開發 MQTT 客戶端。

Eclipse Mosquitto 官方網站

GitHub - eclipse-mosquitto/mosquitto: Eclipse Mosquitto - An open source MQTT broker github開源網站

Mosquitto 服務器安裝

1.下載 openssl 加密庫源碼

Old 1.1.1 Releases | OpenSSL Library

2.下載cjson 源碼

GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C

3.下載mosquitto 服務器

Index of /files/source/

4.配置&安裝??

將下載好文件放到一個自己知道的路徑,然后用wsl打開解壓到家目錄。不要解壓到共享文件里。

------- openssl加密庫安裝---------
tar  -xvf   openssl-1.1.1q.tar.gz   -C    ~/   #1.解壓源碼 
cd  ~/openssl-1.1.1q/                          #2.進入源碼目錄  
./config                                       #3.默認配置  make   test  -j12                             #4.編譯測試代碼與庫文件sudo  make  install                           #5.安裝  ------cjson庫安裝-------cp  cJSON-master.zip   ~/    #1.拷貝到家目錄cd  ~/                       #2.進入家目錄sudo apt install unzip       #3.安裝解壓工具 unzip  cJSON-master.zip      #4.解壓json源碼 cd  cJSON-master/            #5.進入json源碼make                         #6.編譯源碼sudo  make install           #7.安裝 -----安裝mosquitto代理服務器-----
sudo  apt-get install   g++                     #1.安裝g++編譯器
tar  -xvf  mosquitto-2.0.9.tar.gz   -C   ~/     #2.解壓到家目錄  
cd  ~/mosquitto-2.0.9/                          #3.進入源碼目錄   
make                                            #4.編譯  
sudo  make  install                             #5.安裝 tip💡如果cjson庫或ssl 庫安裝失敗    
cJSON - for client JSON output support. Disable with make WITH_CJSON=no Auto detected with CMake.make WITH_CJSON=no   #去掉cjson openssl (libssl-dev on Debian based systems) - disable with make WITH_TLS=nomake WITH_TLS=no

測試成功如下

四、mosquitto 代理服務器使用

1、訂閱與發布命令

 #拷貝庫文件到系統庫中 sudo  cp  /usr/local/lib/lib*   /lib#拷貝系統的配置文件 cp  /etc/mosquitto/mosquitto.conf.example   ./  //當前文件為自己寫代碼的文件里

2、修改端口

3、關閉防火墻

#開啟代理服務器  嘗試能不能行mosquitto  -c  ./mosquitto.conf.example#訂閱主題   'test/topic' mosquitto_sub -t 'test/topic' -v#發布消息   mosquitto_pub -t 'test/topic' -m 'hello world'

4、發布端函數接口

將官方大的代碼拷貝到自己寫代碼的文件里邊看官方代碼邊寫自己的代碼。

//1初始化MQTT庫,在調用任何函數之前必須要調用該函數 
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.//2創建一個新的客戶端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客戶端ID,如何為NULL ,系統自動分配一個ID,且clean_session參數必須為 true 
clean_session:  true   代理服務器在客戶端斷開后會清除數據 false  代理服務器在客戶端斷開后會保留數據 
obj:傳遞給回調函數的參數  
返回值:成功   客戶端對象地址      失敗    NULL //3連接MQTT服務器 
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客戶端對象  
host:服務器IP地址 
port:服務器端口號 👉1883 
keepalive:保持連續ping 包,設置一段時間后發送一個ping給服務器 
返回值: MOSQ_ERR_SUCCESS - on success.//4啟動網絡線程,不斷處理網絡數據   
int mosquitto_loop_start(struct mosquitto *mosq);
mosq:客戶端對象  
返回值: MOSQ_ERR_SUCCESS - on success.//5?重點,難點 : 發布消息 
int mosquitto_publish(struct mosquitto *mosq, //客戶端對象  int *mid,  //消息ID ,設置為 NULL 即可const char *topic, //👍發布的消息主題int payloadlen,   //發布消息長度   between 0 and 268,435,455.const void *payload, //發布的消息int qos,  //👍消息質量  0 ,1 , 2bool retain); //消息保留標記為  true 保留消息

qos 消息質量

MQTT(Message Queuing Telemetry Transport)協議定義了三種消息質量等級(QoS),以確保在不同場景下消息的可靠傳輸。
以下是三種QoS級別的詳細說明:
1. QoS 0(At Most Once,最多一次)
特點:消息最多被傳遞一次,沒有確認機制,消息可能會丟失或重復。
適用場景:適用于對消息完整性要求不高的場景,如天氣更新、實時數據流、傳感器數據等。在這些場景中,即使消息丟失或重復,也不會造成重大影響。
傳輸過程:發送方發送消息后,不等待接收方的確認,也不存儲消息以進行重傳。
2. QoS 1(At Least Once,至少一次)
特點:消息至少被傳遞一次,但可能會出現重復的消息。
適用場景:適用于對消息丟失敏感,但對重復不敏感的場景,如傳感器數據、開關狀態同步等。在這些場景中,確保消息到達比避免重復更重要。
傳輸過程:發送方發送消息后,會等待接收方的確認報文(PUBACK)。如果未收到確認,發送方會重傳消息。接收方收到消息后,會發送PUBACK確認報文。
3. QoS 2(Exactly Once,僅一次)
特點:消息確保只傳遞一次,沒有重復。這是最高級別的QoS,適用于對消息的完整性和順序性要求非常高的場景。
適用場景:適用于金融交易、關鍵命令等場景,在這些場景中,消息的丟失或重復都是不可接受的。
傳輸過程:發送方和接收方通過四次握手過程(PUBREC、PUBREL、PUBCOMP)來確保消息只被接收一次。發送方發送消息后,等待接收方的PUBREC確認,然后發送PUBREL,最后等待接收方的PUBCOMP確認。
QoS級別的選擇
QoS 0:適用于實時性要求高,但對數據丟失和重復容忍度較高的場景。
QoS 1:適用于需要確保消息至少被接收一次,但允許重復的場景。
QoS 2:適用于需要確保消息僅被接收一次,且對實時性要求不高的場景。
注意事項
網絡條件:在網絡條件較差的情況下,建議選擇較低的QoS級別,以減少消息丟失的風險。
系統資源:QoS級別越高,傳輸過程的復雜程度和系統資源消耗也越大。
綜上所述,根據具體的應用場景和需求選擇合適的QoS級別,可以在確保消息可靠傳輸的同時,優化系統性能和資源利用率。

??發布端代碼例子:

#include <mosquitto.h> //??聲明MQTT庫的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc, char *argv[])
{// 1.初始化MQTT庫mosquitto_lib_init();// 2.創建一個客戶端struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);if (mosq == NULL){perror("創建客戶端失敗\n");return 1;}else{printf("創建客戶成功\n");}// 3.連接服務器,超時設置為60秒int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);if (ret != MOSQ_ERR_SUCCESS){perror("連接服務器失敗\n");return 1;}else{printf("連接服務器成功\n");}// 4.啟動網絡線程mosquitto_loop_start(mosq);while (1){printf("請輸入發布的主題和消息\n");char topic[50] = {0};char payload[268] = {0};scanf("%s %s", topic, payload);int ret = mosquitto_publish(mosq, NULL, topic, strlen(payload), payload, 0, false);if (ret != MOSQ_ERR_SUCCESS){perror("發布消息失敗\n");return 1;}else{printf("發布消息成功\n");}}mosquitto_destroy(mosq); //銷毀對象mosquitto_lib_cleanup(); //清空函數庫 
}

5、訂閱端函數接口

//1.初始化MQTT庫,在調用任何函數之前必須要調用該函數 
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.//2。創建一個新的客戶端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客戶端ID,如何為NULL ,系統自動分配一個ID,且clean_session參數必須為 true 
clean_session:  true   代理服務器在客戶端斷開后會清除數據 false  代理服務器在客戶端斷開后會保留數據 
obj:傳遞給回調函數的參數  
返回值:成功   客戶端對象地址      失敗    NULL //3.連接MQTT服務器 
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客戶端對象  
host:服務器IP地址 
port:服務器端口號 👉1883 
keepalive:保持連續ping 包,設置一段時間后發送一個ping給服務器 (超時時間)
返回值: MOSQ_ERR_SUCCESS - on success.//4.訂閱主題  
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos);
mosq:客戶端對象
mid:消息ID,設置為NULL不關心
sub:👍需要訂閱的主題 
qos:消息質量 0,1,2
返回值: MOSQ_ERR_SUCCESS - on success.//5.?重點,難點:設置消息回調函數,當訂閱的主題有消息時,會調用該函數
void mosquitto_message_callback_set(struct mosquitto *mosq, 
void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *));
mosq:客戶端對象
on_message:函數指針,指向一個回調函數如下👇
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{/* This blindly prints the payload, but the payload can be anything so take care. */printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}
mosq:客戶端對象 
obj:創建客戶端時傳遞的參數 
msg:👍消息💡消息結構體 
struct mosquitto_message{int mid;      //發布消息id char *topic;  //主題void *payload; //消息 int payloadlen; //消息長度  int qos;        //通信質量 bool retain;    //保留消息標記
};6.循環接收消息   int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets);mosq:客戶端對象   timeout:超時檢測 ,設置 -1 永久等待    

訂閱端代碼例子:

#include <mosquitto.h> //??聲明MQTT庫的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{/* This blindly prints the payload, but the payload can be anything so take care. */printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}int main(int argc, char *argv[])
{// 1.初始化MQTT庫mosquitto_lib_init();// 2.創建一個客戶端struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);if (mosq == NULL){perror("創建客戶端失敗\n");return 1;}else{printf("創建客戶成功\n");}// 3.連接服務器int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);if (ret != MOSQ_ERR_SUCCESS){perror("連接服務器失敗\n");return 1;}else{printf("連接服務器成功\n");}// 4.訂閱一個主題ret = mosquitto_subscribe(mosq, NULL, "test", 0);if (ret != MOSQ_ERR_SUCCESS){perror("訂閱失敗\n");return 1;}else{printf("訂閱成功\n");}// 5.設置消息回調函數mosquitto_message_callback_set(mosq, on_message); // 設置接收消息回調函數// 6.循環接收消息mosquitto_loop_forever(mosq, -1, 1); // 一直循環接收數據mosquitto_destroy(mosq);mosquitto_lib_cleanup();return 0;
}

五、MQTTX 調試助手

公共測試服務器:免費的公共 MQTT 服務器 | EMQ

MQTTX 下載

安裝

設置為簡體中文

主題的訂閱與發布調試

1.新建鏈接:服務器為你寫代碼的地址。

2.主題訂閱:主題名字隨便

3.主題發布,要跟代碼的訂閱一樣。

4.實現MQTT遠程通信

即在調試助手中(發送端)發送消息到阿里云(部署MQTT代理服務器)中,然后MQTT代理服務器轉換到Ubuntu的終端中。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/76528.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/76528.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/76528.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構與算法——鏈表OJ題詳解(2)

文章目錄 一、前言二、OJ續享2.1相交鏈表2.2環形鏈表12.2環形鏈表2 三、總結 一、前言 哦了兄弟們&#xff0c;咱們上次在詳解鏈表OJ題的時候&#xff0c;有一部分OJ題呢up并沒有整理完&#xff0c;這一個星期呢&#xff0c;up也是在不斷的學習并且沉淀著&#xff0c;也是終于…

SQL Server AlwaysOn (SQL 查詢數據詳解及監控用途)

修正后的完整查詢 SELECT ar.replica_server_name AS [副本名稱],ar.availability_mode_desc AS [同步模式],DB_NAME(dbr.database_id) AS [數據庫名稱],dbr.database_state_desc AS [數據庫狀態],dbr.synchronization_state_desc AS [同步狀態],dbr.synchronization_health_d…

力扣熱題100刷題day63|49.字母異位詞分組

目錄 一、哈希表相關理論 二、思路 核心思路 三、相關題目 四、總結 一、哈希表相關理論 代碼隨想錄刷題day15|&#xff08;哈希表篇&#xff09;242.有效的字母異位詞、383.贖金信-CSDN博客 二、思路 首先&#xff0c;創建一個map集合&#xff0c;遍歷字符串數組&…

愛普生可編程晶振SG8201CJ和SG8200CJ在胃鏡機器人發揮重要作用

在醫療機器人技術高速發展的今天&#xff0c;胃鏡機器人作為胃腸道疾病診斷與治療的創新設備&#xff0c;正逐漸改變傳統診療模式。其復雜精密的系統需要精準的時間同步與穩定的信號輸出&#xff0c;胃鏡機器人是一種先進的醫療設備&#xff0c;用于無創性地檢查胃部疾病。與傳…

Ubuntu22環境下,Docker部署阿里FunASR的gpu版本

番外: 隨著deepseek的爆火,人工智能相關的開發變得異常火爆,相關的大模型開發很常見的agent智能體需要ASR語音識別的功能,阿里開源的FunASR幾乎是把一個商業的項目放給我們使用了。那么我們項目中的生產環境怎么部署gpu版本的語音識別服務呢?經過跟deepseek的一上午的極限…

圖解Java設計模式

1、設計模式面試題 2、設計模式的重要性 3、7大設計原則介紹 3.1、單一職責原則

transformers的 pipeline是什么:將模型加載、數據預處理、推理等步驟進行了封裝

transformers的 pipeline是什么:將模型加載、數據預處理、推理等步驟進行了封裝 pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=50 )pipeline :這是 transformers 庫中一個非常實用的工具函數。它可以基于預訓練模型快速構…

jmeter插件安裝

1、下載 下載地址&#xff1a; Documentation :: JMeter-Plugins.org 然后復制到D:\apache-jmeter-5.6.3\lib\ext 復制后 2、重啟jmeter 在菜單【選項】找到“Plugins Manager” 在 Plugins Manager 界面上&#xff0c;點擊“Available Plugins”標簽頁&#xff0c;可以瀏覽所…

VSCode CMake調試CPP程序

文章目錄 1 安裝C與CMake插件2 配置CMakeLists.txt3 使用CMake編譯調試3.1 編譯3.2 調試 4 自定義構建調試參考 1 安裝C與CMake插件 C插件 CMake插件 2 配置CMakeLists.txt 編寫測試程序 #include<iostream>int main(int argc, char const *argv[]) {int a 1, b 2;i…

【前端】【css】flex布局詳解

Flex 布局&#xff08;Flexible Box Layout&#xff0c;彈性盒子布局&#xff09;是 CSS3 中的一種布局模式&#xff0c;用于在容器中更高效地分配空間并對齊內容&#xff0c;即使它們的大小是動態未知的。它非常適用于響應式設計。 一、Flex 布局的基本概念 1. 啟用 Flex 布局…

LEARNING DYNAMICS OF LLM FINETUNING【論文閱讀筆記】

LEARNING DYNAMICS OF LLM FINETUNING 一句話總結 作者將LLM的學習動力機制拆解成AKG三項&#xff0c;并分別觀察了SFT和DPO訓練過程中??正梯度信號??和??負梯度信號??的變化及其帶來的影響&#xff0c;并得到以下結論&#xff1a; ??SFT通過梯度相似性間接提升無關…

Mac 下載 PicGo 的踩坑指南

Mac 下載 PicGo 的踩坑指南 一、安裝問題 下載地址&#xff1a;https://github.com/Molunerfinn/PicGo/releases 下載之后直接安裝即可&#xff0c;此時打開會報錯&#xff1a;Picgo.app 文件已損壞&#xff0c;您應該將它移到廢紙簍。 這是因為 macOS 為了保護用戶不受惡意…

Element UI 設置 el-table-column 寬度 width 為百分比無效

問題描述&#xff1a; 想要每列寬度不同&#xff0c;不想使用 px 固定值&#xff0c;將 width 設置成百分比&#xff0c;但是每一列還是很窄 原因&#xff1a; el-table 組件會被 vue 解析成 html&#xff0c;vue 直接把百分號去掉把數值當做列寬來呈現&#xff0c;所以&#x…

第五篇:Python面向對象編程(OOP)深度教程

1. 類與對象 1.1 基本概念 ??類??是創建對象的藍圖,定義了對象的??屬性??(數據)和??方法??(行為)。??對象??是類的實例化實體,每個對象擁有獨立的屬性值和共享的類方法 ??示例??:定義Dog類 class Dog:species = "Canis familiaris" …

【數據結構】2.順序表實現通訊錄

文章目錄 一、通訊錄的要求二、通訊錄的具體實現0、 準備工作1、通訊錄的初始化2、通訊錄的銷毀3、通訊錄的展示4、通訊錄添加數據5、通訊錄刪除數據6、通訊錄的查找7、通訊錄的修改8、保存通訊錄數據到文件9、讀取文件內容到通訊錄 三、 通訊錄的完整實現 一、通訊錄的要求 通…

程序化廣告行業(79/89):技術革新與行業發展脈絡梳理

程序化廣告行業&#xff08;79/89&#xff09;&#xff1a;技術革新與行業發展脈絡梳理 大家好&#xff01;一直以來&#xff0c;我都熱衷于在技術領域不斷探索&#xff0c;也深知知識共享對于進步的重要性。寫這篇博客&#xff0c;就是希望能和大家一起深入研究程序化廣告行業…

【C++游戲引擎開發】第9篇:數學計算庫GLM(線性代數)、CGAL(幾何計算)的安裝與使用指南

寫在前面 兩天都沒手搓實現可用的凸包生成算法相關的代碼&#xff0c;自覺無法手搓相關數學庫&#xff0c;遂改為使用成熟數學庫。 一、GLM庫安裝與介紹 1.1 vcpkg安裝GLM 跨平臺C包管理利器vcpkg完全指南 在PowerShell中執行命令&#xff1a; vcpkg install glm# 集成到系…

python文件打包無法導入ultralytics模塊

&#x1f4a5;打包的 .exe 閃退了&#xff1f;別慌&#xff01;教你逐步排查 PyInstaller 打包的所有錯誤&#xff01; &#x1f6e0; 運行 .exe 查看報錯信息? 正確姿勢&#xff1a; ? importlib 動態導入導致打包失敗?什么是動態導入&#xff1f;? 解決方式&#xff1a; …

【React框架】什么是 Vite?如何使用vite自動生成react的目錄?

什么是 Vite&#xff1f; Vite 是一個基于原生 ES Modules 開發的前端構建工具&#xff0c;由 Evan You&#xff08;Vue 的作者&#xff09;開發。它最大的特點包括&#xff1a; 極速冷啟動&#xff1a;因為利用了瀏覽器原生的 ES Modules&#xff0c;所以在開發時無需等待整…

深入解讀 React 純組件(PureComponent)

什么是純組件&#xff1f; React 的純組件(PureComponent)是 React.Component 的一個變體&#xff0c;它通過淺比較(shallow comparison)props 和 state 來自動實現 shouldComponentUpdate() 方法&#xff0c;從而優化性能。 核心特點 1. 自動淺比較&#xff1a; PureCompon…