【嵌入式】MQTT

MQTT

文章目錄

  • MQTT
    • 安裝
    • 簡介
    • MQTT客戶端代碼

安裝

安裝Paho MQTT C庫:

sudo apt-get install libpaho-mqtt3-dev

頭文件包含:

#include "MQTTClient.h"

編譯選項:

gcc -o $@ $^ -lpaho-mqtt3c

簡介

MQTT協議全稱是(Message Queuing Telemetry Transport),即消息隊列遙測傳輸協議。

是一種基于發布/訂閱(Publish/Subscribe)模式的輕量級通訊協議,并且該協議構建于TCP/IP協議之上,TCP協議本身就具有高可靠性的特點,因此基于其上的MQTT協議同樣也是具有高可靠、低開銷的特點,之所以低開銷,是以為MQTT協議傳輸的最小的報文也只有兩個字節。

在物聯網開發中,MQTT不是唯一的選擇,與MQTT互相競爭的協議有XMPP和CoAP協議等。

關于發布和訂閱的概念我們拿抖音平臺來舉個例子,我們每一個用戶就都是一個客戶端,而抖音就是MQTT協議中的服務器,當我們(用戶一)關注某一個視頻發布者(用戶二)時,這樣一個關注的行為就可以理解為訂閱;同時用戶二也可以關注你,那么這就是相互訂閱。當用戶二發布作品的時候,這個作品是發布到了抖音平臺,也就是我們現在的服務器,這個過程就是消息的發布。

在這里需要注意的是:用戶二(客戶端)發布的消息并不是直接發布給了用戶一,而是發布到了抖音平臺(服務器),由于用戶一訂閱了用戶二的消息(相當于點了關注),所以抖音平臺(服務器)就會向用戶一推送這個消息(注意發布和推送的區別)。這就是MQTT協議訂閱&發布的一個簡單比喻。

img

img

實現MQTT協議需要客戶端和服務器端通訊完成,在通訊過程中,MQTT協議中有三種身份:發布者(Publish)、代理(Broker)(服務器)、訂閱者(Subscribe)。其中,消息的發布者和訂閱者都是客戶端,消息代理是服務器,消息發布者可以同時是訂閱者。

MQTT傳輸的消息分為:主題(Topic)和負載(payload)兩部分

  • Topic,可以理解為消息的類型,訂閱者訂閱(Subscribe)后,就會收到該主題的消息內容(payload)
  • payload,可以理解為消息的內容,是指訂閱者具體要使用的內容

MQTT客戶端代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"#define ADDRESS "thirdparty.mqtt.yoplore.com"  //服務器的IP地址
#define CLIENTID "client01"   //發布者的姓名(唯一的,如果發布者和訂閱者用同一個姓名,就會出現頂號的現象)
#define TOPIC1 "MQTT topic/topic1"              //訂閱主題
#define TOPIC2 "MQTT topic/topic2"              //訂閱主題
#define QOS 1                              //服務登記(0.最多一次,1.最少一次,2.確保一次)
#define TIMEOUT 10000L                     //響應時間//定義一個傳遞令牌
volatile MQTTClient_deliveryToken deliveredtoken;//令牌交付回調函數,當消息成功交付給 MQTT 服務器時調用
/**context:用戶自定義的上下文指針,此處未使用dt:消息交付的令牌
*/
void delivered(void *context, MQTTClient_deliveryToken dt)
{printf("Message with token value %d delivery confirmed\n", dt);deliveredtoken = dt;
}//接受訂閱信息的回調函數,當接收到訂閱主題的消息時調用
/**context:用戶自定義的上下文指針,此處未使用topicName:接收到消息的主題名稱topicLen:主題名稱的長度message:接收到的 MQTT 消息結構體指針
*/
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{int i;char *payloadptr;printf("Message arrived\n");printf("topic: %s\n", topicName);printf("message: ");payloadptr = message->payload;for (i = 0; i < message->payloadlen; i++){putchar(*payloadptr);payloadptr++;}putchar('\n');MQTTClient_freeMessage(&message);MQTTClient_free(topicName);return 1;
}
//斷開鏈接的回調函數
void connlost(void *context, char *cause)
{printf("\nConnection lost\n");printf("cause: %s\n", cause);
}int main(int argc, char *argv[])
{printf("\nCreating MQTTClient\n");// 消息緩沖區char buf[1024];// 1、定義一個MQTT客戶端結構體指針MQTTClient client;// 2、創建一個MQTT客戶端MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;MQTTClient_create(&client, ADDRESS, CLIENTID,MQTTCLIENT_PERSISTENCE_NONE, NULL);conn_opts.keepAliveInterval = 20;// 連接保活時間conn_opts.cleansession = 1; // 設置是否清除會話,1為清除// 定義一個 MQTT 消息結構體,用于存儲要發布的消息MQTTClient_message publish_msg=MQTTClient_message_initializer;// 令牌tokenMQTTClient_deliveryToken token;// 設置回調MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);// 鏈接int rc = MQTTClient_connect(client, &conn_opts);if (rc != MQTTCLIENT_SUCCESS) {printf("Failed to connect, return code %d\n", rc);return EXIT_FAILURE;}// 訂閱多個主題rc = MQTTClient_subscribe(client, TOPIC1, QOS);if (rc != MQTTCLIENT_SUCCESS) {printf("Failed to subscribe to %s, return code %d\n", TOPIC1, rc);return EXIT_FAILURE;}rc = MQTTClient_subscribe(client, TOPIC2, QOS);if (rc != MQTTCLIENT_SUCCESS) {printf("Failed to subscribe to %s, return code %d\n", TOPIC2, rc);return EXIT_FAILURE;}//用戶退出char ch;while (1) {// 發送信息printf("請輸入要發布的內容(輸入 'q' 或 'Q' 退出):\n");if (fgets(buf, sizeof(buf), stdin) == NULL) {printf("讀取輸入失敗\n");continue;}// 去除換行符(fgets會將換行符一并讀取)size_t len = strlen(buf);if (len > 0 && buf[len - 1] == '\n') {buf[len - 1] = '\0';}// 檢查是否退出if (buf[0] == 'q' || buf[0] == 'Q') {break;}publish_msg.payload = (void *)buf;publish_msg.payloadlen = strlen(buf);rc = MQTTClient_publishMessage(client, TOPIC2, &publish_msg, &token);//用于將消息發布到指定的主題if (rc != MQTTCLIENT_SUCCESS) {printf("Failed to publish message, return code %d\n", rc);continue;}rc = MQTTClient_waitForCompletion(client, token, 1000); //用于等待指定的消息交付完成if (rc != MQTTCLIENT_SUCCESS) {printf("Failed to wait for message completion, return code %d\n", rc);continue;}printf("buf中的內容: %s\n", buf);}MQTTClient_disconnect(client,10000);MQTTClient_destroy(&client);printf("\nExiting\n");return 0;
}

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

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

相關文章

ubuntu離線安裝nvidia-container-runtime

參考文章 ubuntu系統docker20.4版本安裝nvidia-container-runtime3.11.0-1版本(離線安裝nvidia-docker) - jokerMM - 博客園 https://zhuanlan.zhihu.com/p/15194336245 一、軟件地址 Index of /nvidia-docker/libnvidia-container/stable/ 從上述地地址——進入對應系統—…

用Python+Flask打造可視化武俠人物關系圖生成器:從零到一的實戰全記錄

用PythonFlask打造可視化武俠人物關系圖生成器&#xff1a;從零到一的實戰全記錄 一、緣起&#xff1a;一個程序小白的奇妙探索之旅 作為一個接觸Python僅13天的編程萌新&#xff0c;我曾以為開發一個完整的應用是遙不可及的事情。但在DeepSeek的幫助下&#xff0c;我竟用短短…

RPA 職業前景:個人職場發展的 “新機遇”

1. RPA職業定義與范疇 1.1 RPA核心概念 機器人流程自動化&#xff08;RPA&#xff09;是一種通過軟件機器人模擬人類操作&#xff0c;自動執行重復性、規則性任務的技術。RPA的核心在于其能夠高效、準確地處理大量數據和流程&#xff0c;減少人工干預&#xff0c;從而提高工作…

Full GC 排查

在 Java 中&#xff0c;Full GC&#xff08;完全垃圾回收&#xff09;會對整個堆&#xff08;包括年輕代和老年代&#xff0c;甚至可能包括永久代/元空間&#xff09;進行垃圾回收&#xff0c;通常會導致較長的停頓&#xff08;STW&#xff0c;Stop-The-World&#xff09;。如果…

go語言中字符串嵌套

在Go語言中&#xff0c;字符串嵌套通常是指在字符串中包含另一個字符串。可以通過以下幾種方式實現&#xff1a; 1. 使用雙引號和轉義字符 如果需要在字符串中嵌套雙引號&#xff0c;可以使用轉義字符 \ 來表示內部的雙引號。例如&#xff1a; s : "He said, \"He…

Docker 學習(二)——基于Registry、Harbor搭建私有倉庫

Docker倉庫是集中存儲和管理Docker鏡像的平臺&#xff0c;支持鏡像的上傳、下載、版本管理等功能。 一、Docker倉庫分類 1.公有倉庫 Docker Hub&#xff1a;官方默認公共倉庫&#xff0c;提供超過10萬鏡像&#xff0c;支持用戶上傳和管理鏡像。 第三方平臺&#xff1a;如阿里…

js的簡單介紹

一.javascript&#xff08;是什么&#xff09; 是一種運行在客戶端(瀏覽器)的編程語言&#xff0c;實現人機交互效果 作用 網頁特效&#xff08;監聽客戶的一些行為讓網頁做出對應的反饋&#xff09;表單驗證(針對表格數據的合法性進行判斷)數據交互(獲取后臺的數據&#xf…

k8s架構及服務詳解

目錄 1.1.容器是什么1.2.Namespace1.3.rootfs5.1.Service介紹5.1.1.Serice簡介 5.1.1.1什么是Service5.1.1.2.Service的創建5.1.1.3.檢測服務5.1.1.4.在運行的容器中遠程執行命令 5.2.連接集群外部的服務 5.2.1.介紹服務endpoint5.2.2.手動配置服務的endpoint5.2.3.為外部服務…

01. HarmonyOS應用開發實踐與技術解析

文章目錄 前言項目概述HarmonyOS應用架構項目結構Ability生命周期 ArkTS語言特性裝飾器狀態管理 UI組件與布局基礎組件響應式布局樣式與主題 頁面路由與參數傳遞頁面跳轉參數接收 數據綁定與循環渲染數據接口定義循環渲染 條件渲染組件生命周期最佳實踐與性能優化組件復用響應式…

【虛擬機 IP 配置深度剖析】

虛擬機 IP 配置深度剖析 在虛擬機的使用過程中&#xff0c;IP 配置猶如搭建房屋的基石&#xff0c;是確保虛擬機與外部網絡順暢通信、與其他設備高效交互的關鍵所在。本文將以 CentOS 虛擬機為例&#xff0c;深入解讀 IP 配置的奧秘。 一、認識網絡模式 ? NAT 模式&#xf…

【Python 數據結構 5.棧】

目錄 一、棧的基本概念 1.棧的概念 2.入棧 入棧的步驟 3.出棧 出棧的步驟 4.獲取棧頂元素 獲取棧頂元素的步驟 二、 Python中的棧 順序表實現 鏈表實現 三、棧的實戰 1.LCR 123. 圖書整理 I 思路與算法 2.LCR 027. 回文鏈表 思路與算法 3.1614. 括號的最大嵌套深度 思路與算法 …

Machine Learning 初探

前置知識 pandas 讀取文件&#xff1a;read_csv查看信息 describe&#xff1a;查看整體信息&#xff0c;包括每列的平均值、最大最小值、標準差等head&#xff1a;輸出頭部幾行數據columns&#xff1a;輸出所有列名loc&#xff1a;查詢數據&#xff0c;或是根據索引取對應的數…

2025年2月個人工作生活總結

本文為 2025年2月工作生活總結。 工作記錄 AI浪潮 AI非常火&#xff0c;春節至今&#xff0c;到處充斥著大量和AI、DeepSeek有關的新聞。領導也一再強調要用AI&#xff0c;甚至納入到新一年的考核里。再往上&#xff0c;大領導開會的新聞稿里也作出要求&#xff0c;不能停下腳…

SpringBoot @ConfigurationProperties 注解使用

ConfigurationProperties 用于將配置文件&#xff08;如 application.properties 或 application.yml&#xff09;中的屬性批量綁定到一個 Java Bean 中。 1. 定義配置文件 在 application.properties 或 application.yml 中定義一組具有相同前綴的屬性。 application.yml &a…

剛安裝docker并啟動docker服務: systemctl restart docker報錯解決

root:/home/lzw# sudo systemctl restart docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xeu docker.service" for details. 1、問題描述 啟動doc…

JavaScript的this指向,一次徹底講清楚

JavaScript 中的 this 指向是一個非常重要且容易混淆的概念。它的值取決于函數被調用的上下文,而不是函數定義的位置。以下是 this 指向的詳細解析: 1. 默認綁定(Default Binding) 在非嚴格模式下,如果函數是直接調用(而不是作為對象的方法或構造函數等),this 默認指向…

MFC: 控件根據文本內容大小自動調整

背景&#xff1a; 針對不同語言下&#xff0c;控件顯示不全的現象&#xff1b; 例如&#xff1a; 現象1&#xff1a;中文下顯示全部信息&#xff0c;英語下只能顯示部分文字 現象2&#xff1a;中文下顯示不全## 實現思路&#xff1a; 控件綁定按鈕計算控件文本長度根據文本長…

SpringBoot 整合mongoDB并自定義連接池,實現多數據源配置

要想在同一個springboot項目中使用多個數據源&#xff0c;最主要是每個數據源都有自己的mongoTemplate和MongoDbFactory。mongoTemplate和MongoDbFactory是負責對數據源進行交互的并管理鏈接的。 spring提供了一個注解EnableMongoRepositories 用來注釋在某些路徑下的MongoRepo…

軟件測試中的BUG

文章目錄 軟件測試的生命周期BugBug 的概念描述 Bug 的要素案例Bug 級別Bug 的生命周期與開發產生爭執怎么辦&#xff1f;【高頻面試題】先檢查自身&#xff0c;Bug 是否描述的不清楚站在用戶角度考慮并拋出問題Bug 的定級要有理有據提?自身技術和業務水平&#xff0c;做到不僅…

泵吸式激光可燃氣體監測儀:快速精準守護燃氣管網安全

在城市化進程加速的今天&#xff0c;燃氣泄漏、地下管網老化等問題時刻威脅著城市安全。如何實現精準、高效的可燃氣體監測&#xff0c;守護“城市生命線”&#xff0c;成為新型基礎設施建設的核心課題。泵吸式激光可燃氣體監測儀&#xff0c;以創新科技賦能安全監測&#xff0…