目录

  • 一、腾讯云平台项目创建
  • 1.新建项目
  • 2.新建产品
  • 3.新建设备
  • 二、基于TCP的MQTT接入
  • 1.接入介绍
  • 2.用户名格式
  • 3.密码格式
  • 4.通过python生成用户名和密码
  • 三、ESP32代码
  • 1.MQTT API参考
  • 2.代码实现
  • 3.结果查看



一、腾讯云平台项目创建

1.新建项目

微信扫码登入腾讯云平台,进入控制台->物联网开发平台。

选择公共实例

mqtt能连接activemq吗 mqtt建立连接_mqtt能连接activemq吗


mqtt能连接activemq吗 mqtt建立连接_mqtt能连接activemq吗_02


输入项目名称,保存后可以看到新创建的项目

mqtt能连接activemq吗 mqtt建立连接_vscode_03


mqtt能连接activemq吗 mqtt建立连接_#define_04

2.新建产品

进入新建的项目中,点击新建产品,连接方式选择WIFI。认证方式选择密钥认证

mqtt能连接activemq吗 mqtt建立连接_#define_05


保存后可以看到产品列表已经有数据了

mqtt能连接activemq吗 mqtt建立连接_#define_06

3.新建设备

产品创建完毕之后,可以看到产品的各种设置,这里选择设备调试->新建设备

mqtt能连接activemq吗 mqtt建立连接_#define_07


mqtt能连接activemq吗 mqtt建立连接_#define_08


新建完毕之后,可以查看设备三元组,这是MQTT密钥用户名和密码生成的关键

mqtt能连接activemq吗 mqtt建立连接_#define_09


到此,项目已经完成创建。

二、基于TCP的MQTT接入

1.接入介绍

根据腾讯云官方介绍,MQTT接入规则如下:

mqtt能连接activemq吗 mqtt建立连接_mqtt能连接activemq吗_10


服务器地址:${productId}.iotcloud.tencentdevices.com

2.用户名格式

username 字段的格式为:
${productId}${deviceName};${sdkappid};${connid};${expiry}
注意:${} 表示变量,并非特定的拼接符号。

其中各字段含义如下:
productId:产品 ID。
deviceName: 设备名称。
sdkappid:固定填12010126。
connid :一个随机字符串。
expiry :表示签名的有效期, 从1970年1月1日00:00:00 UTC 时间至今秒数的 UTF8 字符串。

3.密码格式

password 字段格式为: 
${token};hmac 签名方法
其中 hmac 签名方法字段填写第三步用到的摘要算法,可选的值有 hmacsha256 和 hmacsha1。

4.通过python生成用户名和密码

代码如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import base64
import hashlib
import hmac
import random
import string
import time
import sys
# 生成指定长度的随机字符串
def RandomConnid(length):
    return  ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(length))
# 生成接入物联网通信平台需要的各参数
def IotHmac(productID, devicename, devicePsk):
     # 1. 生成 connid 为一个随机字符串,方便后台定位问题
     connid   = RandomConnid(5)
     # 2. 生成过期时间,表示签名的过期时间,从纪元1970年1月1日 00:00:00 UTC 时间至今秒数的 UTF8 字符串
     expiry   = int(time.time()) + 60 * 60 #可以改大一点
     # 3. 生成 MQTT 的 clientid 部分, 格式为 ${productid}${devicename}
     clientid = "{}{}".format(productID, devicename)
     # 4. 生成 MQTT 的 username 部分, 格式为 ${clientid};${sdkappid};${connid};${expiry}
     username = "{};12010126;{};{}".format(clientid, connid, expiry)
     # 5. 对 username 进行签名,生成token
     secret_key = devicePsk.encode('utf-8')  # convert to bytes
     data_to_sign = username.encode('utf-8')  # convert to bytes
     secret_key = base64.b64decode(secret_key)  # this is still bytes
     token = hmac.new(secret_key, data_to_sign, digestmod=hashlib.sha256).hexdigest()
     # 6. 根据物联网通信平台规则生成 password 字段
     password = "{};{}".format(token, "hmacsha256")
     return {
        "clientid" : clientid,
        "username" : username,
        "password" : password
     }
if __name__ == '__main__':
    print(IotHmac(sys.argv[1], sys.argv[2], sys.argv[3]))

如果电脑里没有python环境的可以直接使用菜鸟的python在线编译器sys.argv[1] :产品ID
sys.argv[2] :设备ID
sys.argv[3] :密钥

mqtt能连接activemq吗 mqtt建立连接_mqtt能连接activemq吗_11

生成结果

{
'clientid': 'BENLB3UA1Udriver1', 
'username': 'BENLB3UA1Udriver1;12010126;8MOBM;1646362197',
'password': '9d7188b616aaf81d1a2054a9bf420883a7a6addfa012e17afafe3b38a5b0c147;hmacsha256'
}

三、ESP32代码

1.MQTT API参考

头文件:components/mqtt/esp-mqtt/include/mqtt_client.h

mqtt api接口(仅列出目前使用的部分):

//创建MQTT句柄,成功返回句柄,不成功返回NULL
//config: mqtt 配置结构
esp_mqtt_client_handle_t esp_mqtt_client_init(constesp_mqtt_client_config_t *config);
//注册MQTT事件
//client: mqtt 客户端句柄
//event: 事件类型
//event_handler: 处理程序回调
//event_handler_arg: 处理程序上下文
esp_err_t esp_mqtt_client_register_event(esp_mqtt_client_handle_tclient, esp_mqtt_event_id_tevent, esp_event_handler_tevent_handler, void *event_handler_arg);
//使用已创建的客户端句柄启动 mqtt 客户端
//client: mqtt 客户端句柄
esp_err_t esp_mqtt_client_start(esp_mqtt_client_handle_tclient);

2.代码实现

提示:连接MQTT之前请先确保WIFI连接成功

mqtt宏定义:

#define MQTT_KEEPALIVE  120										//心跳
#define ClientID 		"BENLB3UA1Udriver1"						//客户端ID
#define SERVER_IP 		"BENLB3UA1U.iotcloud.tencentdevices.com"//服务器IP
#define SERVER_PORT 	1883 									//端口号
//用户名和密码可使用python完成
#define Username 		"BENLB3UA1Udriver1;12010126;8MOBM;1646362197"//用户名
#define Password        "9d7188b616aaf81d1a2054a9bf420883a7a6addfa012e17afafe3b38a5b0c147;hmacsha256"//密码

主函数:

void app_main(void)
{
    ESP_LOGI(TAG, "[APP] Startup..");
    ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
    ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());

    esp_log_level_set("*", ESP_LOG_INFO);
    esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE);
    esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT_BASE", ESP_LOG_VERBOSE);
    esp_log_level_set("esp-tls", ESP_LOG_VERBOSE);
    esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
    esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE);

    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK(example_connect());//官方测试用wifi连接函数,一般不使用

    mqtt_app_start();
}

mqtt函数:

static void mqtt_app_start(void)
{
    esp_mqtt_client_config_t mqtt_cfg = {
        .host = SERVER_IP,              //MQTT 地址
		.port = SERVER_PORT,            //MQTT端口
        .client_id = ClientID,          //连接ID
        .keepalive = MQTT_KEEPALIVE,    //心跳时间
		.username = Username,           //用户名字
		.password = Password,           //密码
    };
    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, NULL);
    esp_mqtt_client_start(client);
}

事件回调:

static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id);
    esp_mqtt_event_handle_t event = event_data;
    esp_mqtt_client_handle_t client = event->client;
    switch ((esp_mqtt_event_id_t)event_id) {
    case MQTT_EVENT_CONNECTED:	//连接成功
        ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
        break;
    case MQTT_EVENT_DISCONNECTED:	//断开连接
        ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
        break;
    case MQTT_EVENT_SUBSCRIBED:	//订阅
        break;
    case MQTT_EVENT_UNSUBSCRIBED:	//取消订阅
        break;
    case MQTT_EVENT_PUBLISHED:	//发布
        break;
    case MQTT_EVENT_DATA:	//订阅消息
        ESP_LOGI(TAG, "MQTT_EVENT_DATA");
        printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
        printf("DATA=%.*s\r\n", event->data_len, event->data);
        break;
    case MQTT_EVENT_ERROR:	//错误
        ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
        break;
    default:
        ESP_LOGI(TAG, "Other event id:%d", event->event_id);
        break;
    }
}

3.结果查看

mqtt能连接activemq吗 mqtt建立连接_mqtt能连接activemq吗_12

mqtt能连接activemq吗 mqtt建立连接_#define_13


提示:本篇仅作为学习记录,切勿当做标准教程,如有错误,欢迎提出指正。