【玩转ESP32】14、esp32 mqtt client

2021-07-23 14:19:16 浏览数 (1)

点击上方[物联网思考],选择置顶,第一时间查看物联网分享!

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_idhostusername 需要根据实际情况替换。

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——————

0 人点赞