MQTT中文站
  • 首页
  • MQTT 学习
    • MQTT 入门
    • MQTT 进阶
    • MQTT 编程
    • MQTT 实例
    • MQTT 要点
    • MQTT5 要点
    • MQTT 工具
    • MQTT 客户端库
    • MQTT 服务器
    • Zigbee2MQTT
    • Sparkplug
    • Home Assistant
    • Node-RED
      • Node-RED 安装部署
      • Node-RED 用户指南
      • Node-RED 创建节点
      • Node-RED 示例教程
      • Node-RED 开发流程
      • Node-RED 接口参考
      • Node-RED 配置模板
      • Node-RED 常见问题
  • MQTT 规范
    • MQTT 5 规范
    • MQTT 3.1.1 规范
    • MQTT 3.1 规范
    • MQTT-SN v1.2规范
    • Sparkplug® v3.0.0规范
  • 产品中心
  • 解决方案
    • 环境监测
    • 工业制造
    • 智慧水利
    • 水利管网
    • 积水监测
    • 综合管廊
    • 档案库房
    • 交通物流
    • 智慧城市
    • 智慧农业
    • 智慧养殖
    • 能源电力
    • 石油石化
    • 智能家居
    • 物联网
    • 汽车与出行
  • 使用文档
  • MQTT 云平台
  • 登录
  • 注册

深入ESP32的MQTT API:配置、连接与消息传递

2 年前 • MQTT 教程

MQTT协议

MQTT协议是一个应用层协议,他要求使用的传输层协议能提供有序的,可靠的双向字节流传输服务。

MQTT协议通信对象分为客户端和服务端,数据的传输以消息为单位,每个消息包含主题,消息服务质量和有效数据。消息的发送和接收都需要依赖主题:A订阅主题T1,B订阅主题T2,A想发送消息给B,就需要将消息发送到主题T2。

一,客户端

通信双方的身份。mqtt通信双方都是客户端,消息传递是以订阅主题的形式。

  • 发布消息到服务端以转发到其他客户端
  • 订阅主题以接收其他客户端的消息
  • 发起连接/断开

二,服务端

作为客户端与客户端之间通信的中介。

  • 接收客户端发布的消息
  • 接收客户端的连接
  • 转发消息给特定的客户端
  • 接收客户端的订阅主题请求

三,消息服务质量

消息服务质量决定了一个MQTT报文的消息应如何处理。

  • qos0:客户端仅讲报文发送一次,服务端不需要应答,报文是否送达不保证。
  • qos1:客户端发送报文,服务端接收到后必须应答,超时重发。
  • qos2:客户端发送报文,服务端接收到后应答,客户端再次发送一个release报文,服务端发送该报文到指定主题下的客户端,并应答。

qos0-qos2,服务的质量逐步提高。qos2能使客户端对报文的发送有全局的掌控。qos0很不负责任,嫁出去的女儿泼出去的水,不管了。qos1还行。

四,主题

MQTT主题是一个字符串,由服务端维护。客户端通过在服务端订阅主题,可接收来自该主题的消息。客户端可向该主题发送消息,所有订阅该主题的客户端都会受到该消息。实现的方式是:客户端向服务端发送带主题的消息到服务端,由服务端将消息转发给订阅该主题的客户端,所以服务端地位重要。

MQTT主题支持分级,如/Home/BathRoom/Mirror,/Home/LivingRoom/Tv,是同一等级下的主题。

主题也支持通配符#,发送消息到主题 /Home/# 则BathRoom和LivingRoom主题下的客户端都会收到消息。

主题也支持单层通配符+,/Home/+ 则BathRoom和LivingRoom主题下的客户端会受到消息,但/Home/BathRoom/Mirror和/Home/LivingRoom/Tv 不会收到消息,这点需要跟#区别。

五,MQTT控制报文

MQTT协议依靠MQTT控制报文来通信

深入ESP32的MQTT API:配置、连接与消息传递-MQTT中文站

5.1 固定报头

表示控制报文的类型,报文的一些标志位(包括消息服务质量),以及报文剩余的字节长度。

5.2 可变报头

可变报头的内容跟报文类型有关。

包含报文标识符,一个16bit的数据,用于唯一的标记此次通信的报文。当客户端处理完当前报文后,标识符可释放重用。qos0的消息不需要标识符,因为不需要服务端的应答。

5.3 有效载荷

前面都是协议规定必须的,有效载荷是真正的用户数据。不同类型的报文,有效载荷里的数据不同。

5.4 控制报文类型

不同类型的报文,其不同点在于可变报头及有效载荷。就以这两部分看看主要的报文:

5.4.1 连接报文

•可变报头:包含 “使用传输层协议名”(TCP),MQTT协议等级(3.1.1),连接标志,保持连接。

连接标志:指示有效载荷部分的内容。

保持连接:MQTT客户端需要在一个时间内给服务端发送心跳报文,服务端也要在规定时间内应答。由此判断通信双方是否在线。

•有效载荷

由连接标志指示其内容,出现的顺序为:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码。

客户端标志:字符串,用于唯一标志一个客户端。

遗嘱:是一种错误补救方式,当客户端以异常方式断开连接时,服务端长时间未能联系到客户端,则服务端将该客户端的遗嘱消息发布到遗嘱主题。

用户名和密码:字符串,用于识别客户端是否合法。

5.4.2 发布publish

•固定报头:

深入ESP32的MQTT API:配置、连接与消息传递-MQTT中文站

•DUP*:重发标志,是否是一个重发的报文,qos0大咩。

RETAIN:保留标志位。若为1,服务端需要在内存中保留该消息。

•可变报头:主题及报文标识符•有效载荷:应用数据,一般是json字符串。

5.4.3 订阅主题subscribe

可订阅多个主题

•有效载荷:包含一个主题过滤器表示客户端要订阅的主题,消息服务质量qos。主题过滤器是一个字符串,后面跟着一个字节的消息服务质量,组成一组,一个订阅报文可包含多组这样的东西,来支持订阅多个主题。

六,安全

安全的实现主要依赖于传输层协议,推进TLS协议服务端使用8883端口。

轻量加密AES

ESP-MQTT API 指南

概括

ESP-MQTT是一个MQTT协议客户端的应用程序

一,特性

•支持多种传输层协议如:TCP,SSL,Websocket,wws.

•使用url建立连接

•允许一个应用中多个客户端

•支持订阅,发布,认证,遗嘱,保活和3个消息质量

二,应用示例

•protocols/mqtt.tcp[1]:使用tcp,1883 端口

•protocols/mqtt/ssl[2]:使用tcp,端口8883,比较安全

•protocols/mqtt/ssl_psk[3]:使用tcp,基于公钥加密认证,端口8883

•protocols/mqtt/ws[4]:使用websocket,端口80

•protocols/mqtt/wss[5]:使用wss,端口443

三,初始化配置

3.1 URI

当前支持mqtt,mqtts,ws,wss方式

mqtt 使用tcp例子:

•mqtt://mqtt.eclipse.org: MQTT over TCP, default port 1883

•mqtt://mqtt.eclipse.org:1884 MQTT over TCP, port 1884

•mqtt://username:password@mqtt.eclipse.org:1884 MQTT over TCP, port 1884, with username and password

MQTT over SSL samples:

•mqtts://mqtt.eclipse.org: MQTT over SSL, port 8883

•mqtts://mqtt.eclipse.org:8884: MQTT over SSL, port 8884

MQTT over Websocket samples:

ws://mqtt.eclipse.org:80/mqtt

MQTT over Websocket Secure samples:

wss://mqtt.eclipse.org:443/mqtt

最小配置:


const esp_mqtt_client_config_t mqtt_cfg = {
    .uri = "mqtt://mqtt.eclipse.org",
    // .user_context = (void *)your_context
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);

//注册回调函数
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client);
esp_mqtt_client_start(client);

注意,默认mqtt客户端使用事件句柄来处理mqtt的事件,如连接,订阅,发布等等。

3.2 SSL

3.3 遗嘱

MQTT支持使用遗嘱消息,当客户端意外断开连接时,遗嘱消息被服务端发送并用于通知其他客户端。在 esp_mqtt_client_config_t 中可配置遗嘱消息:

•lwt_topic :指向遗嘱消息的主题

•lwt_msg:指向遗嘱消息

•lwt_msg_len:消息有效载荷长度

•lwt_qos:消息服务质量

•lwt_retain:是否保留

3.4 其他配置参数

•disable_clean_session:默认清除会话,对于连接消息,该参数关闭清除会话标志

•keepalive:保活时间,默认120s

•disable_auto_reconnect:关闭自动重连

•user_context:本地参数,用于传递到事件处理句柄

•task_prio:mqtt任务等级,默认5

•task_stack:mqtt堆栈默认6144 bytes,menuconfig可配置

•buffer_size:接收和缓存的长度,默认1024 bytes

•username:连接到broker的用户名(服务器)

•password:连接到broker的密码(服务器)

•client_id:指向客户端id,一般是一个唯一的字符串,可从broker中获取

•host:MQTT broker的ip地址,域名。设置了url会重写该参数

•port:MQTT broker的端口。设置了url会重写该参数

•transport:设置传输协议。设置了url会重写该参数

•refresh_connection_after_ms:在多少时间(ms)后刷新连接

•event_handle:处理mqtt事件的回调函数

•event_loop_handle:mqtt事件组库

更多esp_mqtt_client_config_t的选项,请参考下面API:

3.5 项目配置菜单来配置mqtt

通过idf.py menuconfig项目配置菜单来配置mqtt,在Component config -> ESP-MQTT Configuration

下面的设置是可行的:

•CONFIG_MQTT_PROTOCOL_311[6]:使用3.1.1版本的MQTT协议•CONFIG_MQTT_TRANSPORT_SSL[7], CONFIG_MQTT_TRANSPORT_WEBSOCKET[8]:选择传输层协议•CONFIG_MQTT_CUSTOM_OUTBOX[9]:使用本地邮箱

3.6 事件

mqtt主要围绕以下事件进行数据的处理:

•MQTT_EVENT_BEFORE_CONNECT:客户端初始化完成并开始连接到broker

•MQTT_EVENT_CONNECTED:客户端成功与broker建立连接,客户端准备好接收发送数据

•MQTT_EVENT_DISCONNECTED:客户端由于无法接收或者发送消息而断开连接

•MQTT_EVENT_SUBSCRIBED:broker 确认客户端的订阅请求。保留订阅消息的id

•MQTT_EVENT_UNSUBSCRIBED:broker确认了客户端的取消订阅消息。保留取消订阅消息的id

•MQTT_EVENT_PUBLISHED:broker确认了用户发布的消息。仅对qos为1和2的消息有效,保留发布消息的id

•MQTT_EVENT_DATA:客户端已接收到一个发布的消息。event data包括:消息id,主题名称,数据及数据长度。若数据长度超过buffer大小,则多个MQTT_EVENT_DATA事件会被触发,*current_data_offset和*total_data_len用于保持对数据的追踪。在此可将数据读到缓存中。

•MQTT_EVENT_ERROR:客户端遇到错误。esp_mqtt_error_type_t from error_handle in the event data 可用于判断是哪个类型的错误。

四,API参考

esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config)

根据配置创建mqtt 客户端句柄。

esp_err_t esp_mqtt_client_set_uri(esp_mqtt_client_handle_t client, const char *uri);

设置mqtt连接的url,这个函数通常会重写esp_mqtt_client_init里的配置。

esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client);

开启mqtt客户端

esp_err_t esp_mqtt_client_reconnect(esp_mqtt_client_handle_t client);

用于强制重新连接

esp_err_t esp_mqtt_client_disconnect(esp_mqtt_client_handle_t client);

用于强制从broker中断开连接

esp_err_t esp_mqtt_client_stop(esp_mqtt_client_handle_t client);

停止mqtt客户端任务,不能再event handle中调用。

int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos);

客户端订阅指向服务质量的主题。

•

客户端必须已经连接,该API可被用户任务或mqtt event 回调函数调用。该API使用信号量,所以可能导致一段时间的阻塞。

•

返回:消息id

int esp_mqtt_client_unsubscribe(esp_mqtt_client_handle_t client, const char *topic);

取消订阅指定主题

•客户端必须连接

•线程安全。参考上面

•返回:消息id

int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain);

客户端发布消息到broker

•该API可能会阻塞几秒钟(由于网络,数据长度问题)

•客户端不必连接

•线程安全

•返回:消息id

参数:

•client:客户端句柄

•topic:主题字符串

•data:有效载荷字符串•len:

有效载荷字符串长度

•qos:消息服务质量

•retain:保留消息标志

esp_err_t esp_mqtt_client_destroy(esp_mqtt_client_handle_t client);

销毁mqtt客户端,不能再mqtt回调函数中调用

esp_err_t esp_mqtt_set_config(esp_mqtt_client_handle_t client, const esp_mqtt_client_config_t *config);

设置配置结构体,通常用于更新mqtt配置,再连接之前的回调事件中。

esp_err_t esp_mqtt_client_register_event(esp_mqtt_client_handle_t client,

esp_mqtt_event_id_t event, esp_event_handler_t event_handler, void* event_handler_arg);

注册mqtt事件

参数:

•

client:

•

event:事件类型•

event_handler:事件处理回调函数

event_handler_arg:事件处理回调函数传入参数

int esp_mqtt_client_get_outbox_size(esp_mqtt_client_handle_t client);

获取邮箱大小

六,示例

References

[1] protocols/mqtt.tcp: https://github.com/espressif/esp-idf/tree/a921852/examples/protocols/mqtt/tcp
[2] protocols/mqtt/ssl: https://github.com/espressif/esp-idf/tree/a921852/examples/protocols/mqtt/ssl
[3] protocols/mqtt/ssl_psk: https://github.com/espressif/esp-idf/tree/a921852/examples/protocols/mqtt/ssl_psk
[4] protocols/mqtt/ws: https://github.com/espressif/esp-idf/tree/a921852/examples/protocols/mqtt/ws
[5] protocols/mqtt/wss: https://github.com/espressif/esp-idf/tree/a921852/examples/protocols/mqtt/wss
[6] CONFIG_MQTT_PROTOCOL_311: https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.1/api-reference/kconfig.html#config-mqtt-protocol-311
[7] CONFIG_MQTT_TRANSPORT_SSL: https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.1/api-reference/kconfig.html#config-mqtt-transport-ssl
[8] CONFIG_MQTT_TRANSPORT_WEBSOCKET: https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.1/api-reference/kconfig.html#config-mqtt-transport-websocket
[9] CONFIG_MQTT_CUSTOM_OUTBOX: https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.1/api-reference/kconfig.html#config-mqtt-custom-outbox

打赏赞(2)微海报分享
esp32 mqtt TCP 有效载荷 科技新闻

MQTT客户端开发指南:小熊派Paho MQTT实例

MQTT Assistant:高效的MQTT工具

猜你喜欢

改善基础设施:HiveMQ如何推动智能城市发展

改善基础设施:HiveMQ如何推动智能城市发展

08/07
2024
为什么企业选择全托管HiveMQ云进行MQTT部署

为什么企业选择全托管HiveMQ云进行MQTT部署

07/01
2024
MQTT 赋能工业 PLC 数据采集与应用

MQTT 赋能工业 PLC 数据采集与应用

06/30
2024
  • 解决方案
    • 智能家居
    • 汽车与出行
    • 工业制造
    • 能源电力
    • 石油石化
    • 交通物流
    • 零售
  • 学习
    • MQTT 规范
    • MQTT 教程
    • MQTT 软件
    • MQTT 客户端库
    • MQTT 服务器
    • 工具和应用程序
  • 关于我们
    • 了解创科慧仁
    • 加入创科慧仁
    • 投资者关系
    • 新闻动态
    • 合作伙伴
    • 联系我们
  • 友情链接
    • Modbus中文网
    • 跳动符号官网
    • 物联网世界
    • RFID世界网
    • 深圳物联网协会
    • isoftstone软通动力
    • 中国发展战略学研究会
    • B.P商业伙伴
  • 在线客服
  • 全国客户服务热线
    4006909885
  • 官方公众号
  • 联系邮箱
    contact@mqtt.cn
Copyright © 2025 MQTT中文站. All rights reserved.Designed by nicetheme. 京ICP备20029519号
在线客服

微信咨询

微信咨询

4006909885

服务热线 7*24小时

电话咨询
  • 首页
  • MQTT 学习
    • MQTT 入门
    • MQTT 进阶
    • MQTT 编程
    • MQTT 实例
    • MQTT 要点
    • MQTT5 要点
    • MQTT 工具
    • MQTT 客户端库
    • MQTT 服务器
    • Zigbee2MQTT
    • Sparkplug
    • Home Assistant
    • Node-RED
  • MQTT 规范
    • MQTT 5 规范
    • MQTT 3.1.1 规范
    • MQTT 3.1 规范
    • MQTT-SN v1.2规范
    • Sparkplug® v3.0.0规范
  • 产品中心
  • 解决方案
    • 环境监测
    • 工业制造
    • 智慧水利
    • 水利管网
    • 积水监测
    • 综合管廊
    • 档案库房
    • 交通物流
    • 智慧城市
    • 智慧农业
    • 智慧养殖
    • 能源电力
    • 石油石化
    • 智能家居
    • 物联网
    • 汽车与出行
  • 使用文档
  • MQTT 云平台
  • 登录
  • 注册
 

正在加载评论...
 

您必须登录才能发表评论。

    string(5) "2.0.0"