点击上方[物联网思考],选择置顶,第一时间查看物联网分享!
1、前言
ESP-IDF提供了mqtt组件,在components/mqtt,相关的API位于components/mqtt/esp-mqtt目录下,这个组件是基于https://github.com/tuanpmt/esp_mqtt的 。组件支持MQTT over TCP、SSL with mbedtls、MQTT over Websocket、 MQTT over Websocket Secure;支持订阅、发布、身份验证、遗嘱消息、心跳、以及3个消息等级。
2、API说明
2.1、MQTT客户端配置结构体
代码语言:javascript复制esp_mqtt_client_config_t
通过这个结构体,可以设置回调函数、服务器地址、用户名、client id、密码、证书等,基本上与mqtt相关的参数都可以设置。
2.2、基于配置创建MQTT Client句柄
代码语言:javascript复制esp_mqtt_client_handle_t esp_mqtt_client_init(const esp_mqtt_client_config_t *config);
config
:配置结构体变量指针;
esp_mqtt_client_handle_t
:创建成功返回的mqtt client句柄。
2.3、启动MQTT Client(客户端)
代码语言:javascript复制esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_t client);
client
:mqtt client句柄;
esp_err_t
:返回值为ESP_OK标识启动成功。
2.4、订阅主题
代码语言:javascript复制int esp_mqtt_client_subscribe(esp_mqtt_client_handle_t client, const char *topic, int qos);
client
:mqtt client句柄;
topic
:主题;
qos
:消息质量。
2.5、发布主题
代码语言:javascript复制int esp_mqtt_client_publish(esp_mqtt_client_handle_t client, const char *topic, const char *data, int len, int qos, int retain);
client
:mqtt client句柄;
topic
:主题;
data
:数据;
len
:长度;
qos
:消息质量;
retain
:保持标识。
2.6、MQTT Client重连
代码语言:javascript复制esp_err_t esp_mqtt_client_reconnect(esp_mqtt_client_handle_t client);
client
:mqtt client句柄;
esp_err_t
:返回值为ESP_OK标识启动成功。
2.7、设置MQTT Client配置,一般用于更新配置
代码语言:javascript复制esp_err_t esp_mqtt_set_config(esp_mqtt_client_handle_t client, const esp_mqtt_client_config_t *config);
client
:mqtt client句柄;
config
:配置结构体变量指针;
esp_err_t
:返回值为ESP_OK标识启动成功。
2.8、MQTT Client回调
代码语言:javascript复制static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
event
:事件结构体变量;
在这个函数中可以通过event_id
来处理各种MQTT事件,比如:MQTT_EVENT_CONNECTED
(MQTT链接)、MQTT_EVENT_SUBSCRIBED
(订阅)、MQTT_EVENT_DATA
(MQTT数据)等;订阅主题后,接受MQTT消息,正是通过这个事件来回调的。
3、代码实现
3.1、定义并初始化MQTT Client配置结构体、MQTT Client句柄
代码语言:javascript复制static esp_mqtt_client_handle_t mqtt_client;
//MQTT Client句柄
代码语言:javascript复制static char mqtt_msg[512];
//mqtt接收消息缓冲区
代码语言:javascript复制static esp_mqtt_client_config_t mqtt_cfg = {
.host= IOT_CORE_MQTT_BROKER_URL,
.event_handle = mqtt_event_handler,//注册回调函数
.port = 1883,
.username = mqtt_token,
.client_id = my_clinet_id
};
//定义并初始化MQTT Client配置结构体
client_id
默认使用的是ESP32_%CHIPID%
的形式;
这里要注意,如果mqtt连接断开了,重连的时候最好变换一个client_id
,或者在client_id
中加入时间戳,保证每次都不一样;
client_id
、host
和username
需要根据实际情况替换。
3.2、创建客户端并连接服务器
代码语言:javascript复制static void mqtt_app_start(void)
{
mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
//创建客户端
ESP_ERROR_CHECK(esp_mqtt_client_start(mqtt_client));
//启动客户端,连接服务器
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
3.3、mqtt回调处理
代码语言:javascript复制static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
{
assert(event != NULL);
switch (event->event_id)
{
case MQTT_EVENT_CONNECTED: //mqtt连接事件
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
break;
case MQTT_EVENT_DISCONNECTED: //mqtt断开事件
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED: //mqtt订阅事件
ESP_LOGD(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED: //mqtt取消订阅事件
ESP_LOGD(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED: //mqtt发布事件
ESP_LOGD(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA: //mqtt接收数据事件
ESP_LOGD(TAG, "MQTT_EVENT_DATA, msg_id=%d, %s", event->msg_id, event->topic);
if (event->data_len >= (sizeof(mqtt_msg) - 1))
{
ESP_LOGE(TAG, "Received MQTT message size [%d] more than expected [%d]", event->data_len, (sizeof(mqtt_msg) - 1));
return ESP_FAIL;
}
break;
case MQTT_EVENT_ERROR: //mqtt错误事件
ESP_LOGD(TAG, "MQTT_EVENT_ERROR");
break;
case MQTT_EVENT_BEFORE_CONNECT: //mqtt连接之前,已发生的事件
ESP_LOGD(TAG, "MQTT_EVENT_BEFORE_CONNECT");
break;
default:
break;
}
return ESP_OK;
}
经过以上几个步骤,esp32就可以通过mqtt连接到服务器了。
——————END——————