MQTT 协议入门:轻松上手,快速掌握核心要点


在这里插入图片描述

什么是 MQTT?

MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。

MQTT 的工作原理

要了解 MQTT 的工作原理,首先需要掌握以下几个概念:MQTT 客户端MQTT Broker发布-订阅模式主题QoS

MQTT 客户端

任何运行 MQTT 客户端库的应用或设备都是 MQTT 客户端。例如,使用 MQTT 的即时通讯应用是客户端,使用 MQTT 上报数据的各种传感器是客户端,各种 MQTT 测试工具也是客户端。

MQTT Broker

MQTT Broker 是负责处理客户端请求的关键组件,包括建立连接、断开连接、订阅和取消订阅等操作,同时还负责消息的转发。一个高效强大的 MQTT Broker 能够轻松应对海量连接和百万级消息吞吐量,从而帮助物联网服务提供商专注于业务发展,快速构建可靠的 MQTT 应用。

发布-订阅模式

发布-订阅模式与客户端-服务器模式的不同之处在于,它将发送消息的客户端(发布者)和接收消息的客户端(订阅者)进行了解耦。发布者和订阅者之间无需建立直接连接,而是通过 MQTT Broker 来负责消息的路由和分发。

下图展示了 MQTT 发布/订阅过程。温度传感器作为客户端连接到 MQTT Broker,并通过发布操作将温度数据发布到一个特定主题(例如 Temperature)。MQTT Broker 接收到该消息后会负责将其转发给订阅了相应主题(Temperature)的订阅者客户端。
在这里插入图片描述

主题

MQTT 协议根据主题来转发消息。主题通过 / 来区分层级,类似于 URL 路径,例如:

chat/room/1

sensor/10/temperature

sensor/+/temperature

MQTT 主题支持以下两种通配符:+ 和 #。

  • +:表示单层通配符,例如 a/+ 匹配 a/x 或 a/y。
  • #:表示多层通配符,例如 a/# 匹配 a/x、a/b/c/d。

注意:通配符主题只能用于订阅,不能用于发布。

QoS

MQTT 提供了三种服务质量(QoS),在不同网络环境下保证消息的可靠性。

  • QoS 0:消息最多传送一次。如果当前客户端不可用,它将丢失这条消息。
  • QoS 1:消息至少传送一次。
  • QoS 2:消息只传送一次。

MQTT 的工作流程

在了解了 MQTT 的基本组件之后,让我们来看看它的一般工作流程:

  1. 客户端使用 TCP/IP 协议与 Broker 建立连接,可以选择使用 TLS/SSL 加密来实现安全通信。客户端提供认证信息,并指定会话类型(Clean Session 或 Persistent Session)。
  2. 客户端既可以向特定主题发布消息,也可以订阅主题以接收消息。当客户端发布消息时,它会将消息发送给 MQTT Broker;而当客户端订阅消息时,它会接收与订阅主题相关的消息。
  3. MQTT Broker 接收发布的消息,并将这些消息转发给订阅了对应主题的客户端。它根据 QoS 等级确保消息可靠传递,并根据会话类型为断开连接的客户端存储消息。

开始使用 MQTT:快速教程

下面我们将通过一些简单的示例来展示如何使用 MQTT。在开始之前,需要准备 MQTT Broker 和 MQTT 客户端。

准备 MQTT Broker

您可以选择私有部署或完全托管的云服务来建立自己的 MQTT Broker。或者您也可以使用免费的公共 Broker。

  • 私有部署
    EMQX 是最具扩展性的开源 MQTT Broker,适用于物联网、工业物联网和车联网。您可以运行以下 Docker 命令来安装 EMQX。
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx
  • 全托管的云服务
    通过全托管的云服务启动 MQTT 服务是最便捷的方式。如下图所示,EMQX Cloud 可以在几分钟内启动,并在 AWS、Google Cloud 和 Microsoft Azure 的 17 个区域提供运行支持。

在这里插入图片描述

Server: broker.emqx.io

TCP Port: 1883

WebSocket Port: 8083

SSL/TLS Port: 8883

Secure WebSocket Port: 8084

准备 MQTT 客户端

在本文中,我们将使用 MQTTX 提供的支持浏览器访问的 MQTT 客户端工具,访问地址为 http://www.emqx.io/online-mqtt-client 。 MQTTX 还提供了桌面客户端命令行工具

MQTTX 是一款跨平台的 MQTT 5.0 桌面客户端,可在 macOS、Linux、Windows 操作系统上运行。其用户友好的聊天式界面使用户能够轻松创建多个 MQTT/MQTTS 连接,并进行 MQTT 消息的订阅和发布。

在这里插入图片描述

目前,各种编程语言都拥有成熟的开源 MQTT 客户端库。我们在流行的 MQTT 客户端库和 SDK 中精选了多个编程语言的 MQTT 客户端库,并提供了详细的代码示例,旨在帮助您快速了解 MQTT 客户端的使用。

创建 MQTT 连接

在使用 MQTT 协议进行通信之前,客户端需要创建一个 MQTT 连接来连接到 Broker。

在浏览器中打开 http://www.emqx.io/online-mqtt-client , 点击页面中间的 New Connection 按钮,将看到如下页面。

在这里插入图片描述

我们在 Name 中输入 Simple Demo,然后点击右上角的 Connect 按钮,建立一个 MQTT 连接。如下图所示,表示连接成功。

在这里插入图片描述

通过通配符订阅主题

接下来,我们在上面创建的 Simple Demo 连接中通过通配符订阅主题 sensor/+/temperature,这样就可以接收所有传感器发送的温度数据了。

如下图所示,点击 New Subscription 按钮,在弹出框中的 Topic 字段中输入主题 sensor/+/temperature,QoS 保持默认值 0。

在这里插入图片描述

订阅成功后,会在订阅列表的中间看到新增了一条记录。

在这里插入图片描述

发布 MQTT 消息

接下来,我们点击左侧菜单上的 + 按钮创建两个连接,分别命名为 Sensor 1Sensor 2,用来模拟两个温度传感器。

在这里插入图片描述

连接创建成功后,会看到三个连接,每个连接左侧的在线状态指示灯都是绿色的。

在这里插入图片描述

选择 Sensor 1 连接,在页面下方的发布主题中输入 sensor/1/temperature,在消息框中输入以下 JSON 格式的消息,然后点击右下方的发布按钮发送消息。

{
  "msg": "17.2"
}

在这里插入图片描述

如下图所示,消息发送成功。

在这里插入图片描述

使用相同的步骤,在 Sensor 2 连接中发布以下 JSON 消息到 sensor/2/temperature 主题。

{
  "msg": "18.2"
}

您会看到 Simple Demo 连接收到两条新消息。

在这里插入图片描述

点击 Simple Demo 连接,会看到两个传感器发送的两条消息。

在这里插入图片描述

MQTT 功能演示

保留消息

当 MQTT 客户端向服务器发布消息时,可以设置保留消息标志。保留消息存储在消息服务器上,后续订阅该主题的客户端仍然可以收到该消息。

如下图所示,我们在 Sensor 1 连接中勾选 Retain 选项,然后向 retained_message 主题发送两条消息。

在这里插入图片描述

接着,我们在 Simple Demo 连接中订阅 retained_message 主题。订阅成功后,会收到 Sensor 1 发送的第二条保留消息,这说明服务器只会为主题保留最近的一条保留消息。

在这里插入图片描述

Clean Session

MQTT 客户端通常只能在在线状态下接收其它客户端发布的消息。如果客户端离线后重新上线,它将无法收到离线期间的消息。

但是,如果客户端连接时设置 Clean Session 为 false,并且使用相同的客户端 ID 再次上线,那么消息服务器将为客户端缓存一定数量的离线消息,并在它重新上线时发送给它。

本次演示使用的公共 MQTT 服务器设置为缓存 5 分钟的离线消息,最大消息数为 1000 条,且不保存 QoS 0 消息。

下面,我们创建一个 MQTT 3.1.1 连接,并用 QoS 1 来演示 Clean Session 的使用。

MQTT 5.0 中将 Clean Session 拆分成了 Clean Start 与 Session Expiry Interval。

创建一个名为 MQTT V3 的连接,设置 Clean Session 为 false,选择 MQTT 版本为 3.1.1。

在这里插入图片描述

连接成功后,订阅 clean_session_false 主题,并将 QoS 设置为 1。

在这里插入图片描述

订阅成功后,点击右上角的断开按钮,断开连接。

在这里插入图片描述

然后,创建一个名为 MQTT_V3_Publish 的连接,MQTT 版本也设置为 3.1.1。连接成功后,向 clean_session_false 主题发布三条消息。

在这里插入图片描述

接着,选择 MQTT_V3 连接,点击连接按钮重新连接到服务器,会收到三条离线消息。

在这里插入图片描述

遗嘱消息

MQTT 客户端在向服务器发起 CONNECT 请求时,可以选择是否发送遗嘱消息标志,并指定遗嘱消息的主题和有效载荷。

如果 MQTT 客户端异常离线(在断开连接前没有向服务器发送 DISCONNECT 消息),MQTT 服务器会发布遗嘱消息。

我们创建一个名为 Last Will 的连接来演示这个功能。为了快速看到效果,我们把 Keep Alive 设置为 5 秒。

  • Last-Will Topic 设置为 last_will
  • Last-Will QoS 设置为 1
  • Last-Will Retain 设置为 true
  • Last-Will Payload 设置为 offline

在这里插入图片描述

连接成功后,我们断开电脑网络超过 5 秒(模拟客户端异常断开连接),然后再恢复网络。

接着启动 Simple Demo 连接,并订阅 last_will 主题。您会收到 Last Will 连接设置的遗嘱消息。

在这里插入图片描述
本文详细介绍了 MQTT 的基本概念和使用流程,您可以按照本文所学的内容尝试使用 MQTT 协议。

  • 87
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 131
    评论
以下是使用C++ paho mqtt库中的mqtt::topic发布json对象的示例代码: ```c++ #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <json/json.h> #include "mqtt/async_client.h" using namespace std; const string ADDRESS("tcp://localhost:1883"); const string CLIENTID("AsyncPublisher"); const string TOPIC("test"); const int QOS = 1;const int TIMEOUT = 10000L; class callback : public virtual mqtt::callback { public: virtual void connection_lost(const std::string& cause) { cout << "\nConnection lost" << endl; if (!cause.empty()) cout << "\tcause: " << cause << endl; } virtual void delivery_complete(mqtt::delivery_token_ptr token) { cout << "\n\tDelivery complete for token: " << (token ? token->get_message_id() : -1) << endl; } }; int main(int argc, char* argv[]) { mqtt::async_client client(ADDRESS, CLIENTID); mqtt::connect_options connOpts; connOpts.set_keep_alive_interval(20); connOpts.set_clean_session(true); callback cb; client.set_callback(cb); try { mqtt::token_ptr conntok = client.connect(connOpts); conntok->wait_for_completion(); Json::Value root; root["name"] = "John"; root["age"] = 25; root["email"] = "john@example.com"; string json_str = root.toStyledString(); mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, json_str); pubmsg->set_qos(QOS); mqtt::delivery_token_ptr pubtok = client.publish(pubmsg); pubtok->wait_for_completion(TIMEOUT); cout << "Message '" << json_str << "' published to topic '" << TOPIC << "'" << endl; client.disconnect()->wait_for_completion(); } catch (const mqtt::exception& exc) { cerr << exc.what() << endl; return 1; } return 0; } ``` 在这个示例中,我们使用了Jsoncpp库来创建一个Json对象,并将其转换为字符串。然后,我们使用mqtt::make_message()函数创建一个mqtt::message_ptr对象,该对象包含要发布的主题和消息。最后,我们使用mqtt::async_client类的publish()函数将消息发布到主题上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 131
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿Q说代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值