ESP32连接涂鸦MQTT标准协议失败求助(错误码rc=-4)
涂鸦IoT MQTT连接失败排查求助
问题背景
我参考涂鸦IoT的MQTT协议文档,在开发者平台创建了产品,但ESP32始终无法连接涂鸦MQTT服务器。测试连接公开MQTT服务器(test.mosquitto.org:1883)正常,说明基础MQTT功能没问题。
错误信息
连接时返回:
failed , rc=-4 try again in 5 seconds failed
根据PubSubClient文档,rc=-4表示服务器未在保活时间内响应,尝试将保活时间设为60秒后问题依旧。
代码实现
#include <Seeed_mbedtls.h> #define KEY_SIZE 32 // 256 bits for HMAC-SHA256 #define OUTPUT_SIZE 32 // SHA-256 outputs 32 bytes // Your 256-bit secret key (32 bytes) String str = "DeviceSecret"; const uint8_t* deviceSecret = (const uint8_t*)str.c_str(); #include <WiFi.h> WiFiClient wifiClient; #include <time.h> // include time library // (utc+) TZ in hours long timezone = 0; byte daysavetime = 0; #include <PubSubClient.h> PubSubClient client(wifiClient); // Set up wifi #define SSID "SSID" #define WIFI_PWD "pwd" // MQTT set up #define MQTT_BROKER "m1.tuyacn.com" #define MQTT_PORT (8883) String compute_hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *input, size_t input_len) { mbedtls_md_context_t ctx; const mbedtls_md_info_t *md_info; uint8_t hmac_output[32]; // SHA-256 outputs 32 bytes mbedtls_md_init(&ctx); md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); if (md_info == NULL) { Serial.println("Failed to get MD info for SHA256"); mbedtls_md_free(&ctx); return String(); } if (mbedtls_md_setup(&ctx, md_info, 1) != 0) { Serial.println("Failed to setup MD context"); mbedtls_md_free(&ctx); return String(); } if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) { Serial.println("Failed to start HMAC"); mbedtls_md_free(&ctx); return String(); } if (mbedtls_md_hmac_update(&ctx, input, input_len) != 0) { Serial.println("Failed to update HMAC"); mbedtls_md_free(&ctx); return String(); } if (mbedtls_md_hmac_finish(&ctx, hmac_output) != 0) { Serial.println("Failed to finish HMAC"); mbedtls_md_free(&ctx); return String(); } mbedtls_md_free(&ctx); // Convert the HMAC output to a hexadecimal string String hmac_str; for (int i = 0; i < sizeof(hmac_output); i++) { char buf[3]; sprintf(buf, "%02x", hmac_output[i]); hmac_str += buf; } return hmac_str; } // the setup function runs once when you press reset or power the board void setup() { Serial.begin(9600); Serial.print("Connecting to " SSID); WiFi.begin(SSID, WIFI_PWD); // attempt to connect to an existing wifi //Wait for wifi to connect while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print(" . "); } Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); //Time Server Set up Serial.println("Contacting Time Server"); configTime(3600*timezone, daysavetime*3600, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org"); delay(1000); time_t now; time(&now); //MQTT Credentials set up String MQTT_USERNAME = "deviceID|signMethod=hmacSha256,timestamp=" + String(now) +",secureMode=1,accessType=1"; // Your original const char* message const char *message = "deviceId=deviceID,timestamp=,secureMode=1,accessType=1"; // The String you want to insert String additional = String(now); // Convert the original message to a String String messageString = String(message); // Insert the additional String at the 43rd position size_t insertPos = 42; // Position to insert messageString = messageString.substring(0, insertPos) + additional + messageString.substring(insertPos); // Convert the modified message back to const char* const char* final_message = messageString.c_str(); // Compute HMAC-SHA256 String MQTT_PWD = compute_hmac_sha256(deviceSecret, KEY_SIZE, (const uint8_t *)final_message, strlen(final_message)); Serial.println(now); Serial.print("MQTT_PWD: "); Serial.println(MQTT_PWD); Serial.println("init successfull"); String tuyalink = "tuyalink_DeviceId"; // Handle MQTT connection. client.setServer(MQTT_BROKER, MQTT_PORT); // set broker settings // 尝试过设置更长保活时间,无效 // uint16_t keepAlive = 60; // client.setKeepAlive(keepAlive); while (! client.connected()) { // check connected status if ( client.connect(tuyalink.c_str(),MQTT_USERNAME.c_str(),MQTT_PWD.c_str())){ // connect with random id Serial.println("MQTT connected."); // report success //client.subscribe("Test/ra542"); } else { Serial. printf (" failed , rc=%d try again in 5 seconds", client.state ()); // report error delay(5000); // wait 5 seconds } } } // the loop function runs over and over again forever void loop() { Serial.println("Hello World!"); delay(5000); }
注:代码中已替换实际的deviceId和DeviceSecret,SSID和WiFi密码也已替换为真实值。
已尝试的排查步骤
- 确认WiFi连接正常,能获取IP并访问公网
- 测试连接test.mosquitto.org:1883无凭证连接成功,排除PubSubClient库和ESP32硬件问题
- 增加MQTT保活时间至60秒,问题依旧
- 检查NTP时间同步,已获取到正确的UTC时间
请求帮助
希望得到排查思路或具体的修复建议,比如签名计算是否正确、MQTT参数是否符合涂鸦要求、SSL连接是否有问题等。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

