You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32 PubSubClient使用自签名证书连接MQTT失败返回状态-2

MQTT连接返回-2故障排查

PubSubClient返回状态码-2代表MQTT_CONNECT_FAILED,即底层TCP/TLS连接根本没有建立成功,你的代码存在三个核心问题:

  • 端口与客户端类型不匹配:你使用的WiFiClientSecure是TLS加密客户端,默认对应MQTT over TLS的服务端口是8883,但你配置的1883是明文MQTT端口,加密客户端往明文端口发TLS握手请求会直接被拒绝。
  • 配置顺序错误:你先调用client.setServer()初始化了PubSubClient的服务端绑定逻辑,之后才给WiFiClientSecure加载CA证书,后续连接时根本读不到你设置的证书,TLS校验直接失败。
  • TLS校验规则不匹配:你用IP地址直连broker,但WiFiClientSecure默认开启证书域名校验,你提供的自签名证书的CN、SAN字段没有包含当前连接的IP地址,就算证书加载成功,身份校验也会不通过。
修复方案

根据你是否开启broker的TLS加密,二选一处理:

  1. 如果broker开了TLS加密(你要用自签名证书连接的场景)
    • 把mqtt_port改成broker实际的TLS监听端口(默认是8883)
    • 调整配置顺序:先给WiFiClientSecure加载证书、配置校验规则,再给PubSubClient绑定服务端地址
    • IP直连场景下临时关闭域名校验(正式环境用域名连接时不要开这个配置,会降低安全性)
    • loop函数里必须加client.loop(),不然连接维持逻辑不会跑
  2. 如果broker没开TLS加密
    • 直接删掉WiFiClientSecure相关代码,换成普通WiFiClient,不需要加载任何证书,端口保持1883即可。
修正后的参考代码(TLS加密连接版本)
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// WiFi配置
const char *ssid = "Wokwi-GUEST";
const char *password = "";

// MQTT配置
const char *mqtt_broker = "152.67.151.213";
const char *topic = "esp32/test";
const char *mqtt_username = "********";
const char *mqtt_password = "********";
const int mqtt_port = 8883; // 替换为你broker的实际TLS端口

const char* root_ca PROGMEM = \
    "-----BEGIN CERTIFICATE-----\r\n" \
    "MIIDhzCCAm+gAwIBAgIUViQZNJUlRTBYRkTfljNNUN4sjZowDQYJKoZIhvcNAQEL\r\n" \
    "BQAwUzELMAkGA1UEBhMCTFYxDTALBgNVBAgMBFJpZ2ExDTALBgNVBAcMBFJpZ2Ex\r\n" \
    "CzAJBgNVBAoMAkxVMQwwCgYDVQQLDANTTUkxCzAJBgNVBAMMAkpUMB4XDTIyMDQy\r\n" \
    "NzE3MDQ1NVoXDTI3MDQyNzE3MDQ1NVowUzELMAkGA1UEBhMCTFYxDTALBgNVBAgM\r\n" \
    "BFJpZ2ExDTALBgNVBAcMBFJpZ2ExCzAJBgNVBAoMAkxVMQwwCgYDVQQLDANTTUkx\r\n" \
    "CzAJBgNVBAMMAkpUMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4V/m\r\n" \
    "ZNKfBEoqvHHNK4J6TiRtPKRCcGsNgZAOrAK/isJgOiJaZkJ8Ef6s2Moh4RR6GWi9\r\n" \
    "QabV9cGAcsa3MbcSzTE6pKlw6EcTmMzX3Wg2xFj4TwUJHXOzPUITvXRPl8GOQS2C\r\n" \
    "wlqbOEp7zKnKzfJ/A2nK4CkQZEEJ10AkXzfLiiw0CKHR1KNt23Y8chzfWCU89LBP\r\n" \
    "xISCSwBqofhHtN1w//Gh7SyvtGfFRb87yGPpn3ULoes5EmSkqOo3LEmNyz/3rPdB\r\n" \
    "cCNZnN6z7vk1alUgMqlsFHT48FAE/xgfBqw35VR2dUAaqIwZTyA9giLssPTizw3C\r\n" \
    "REYcIeKCXMWpqa7GRQIDAQABo1MwUTAdBgNVHQ4EFgQU3ezmrWMb7sTUgMJ5JJqR\r\n" \
    "uoXF89EwHwYDVR0jBBgwFoAU3ezmrWMb7sTUgMJ5JJqRuoXF89EwDwYDVR0TAQH/\r\n" \
    "BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcUHWtg2ETX5FJNnKjL5wmP+LPhE8\r\n" \
    "6VhOzXHdQgO2HTuinzZOoD0kYZ6K06loNBq2+nRcl4SEUQKiSajDcsBrFIy47R1o\r\n" \
    "8ztWbM+ALA03FKT6ezWkM75/g6wamyGFoZKQaI71UfW/LVS9AlTPRD4wfcgI6ee0\r\n" \
    "ZT6lXLv6GwnA5z1rrVKWBAbR6/6gdAPVYYj9EszTFRqnWLjHDv16zAyP18TBfYFY\r\n" \
    "7cddN4dQIUnr/gYNsI1k2pCmB0mQuObxhjq2U3p3siTmEAaNAVF1m+9+DDWy/Aar\r\n" \
    "78UuEhtf35C0b6Yj4h7xwNpAmHtikg3HTY0+pciq+bdcPA6buN+eu/eV2Q==\r\n" \
    "-----END CERTIFICATE-----\r\n";
    
WiFiClientSecure espClient;
PubSubClient client(espClient);

void setup() {
 Serial.begin(115200);
 // 连接WiFi
 WiFi.begin(ssid, password);
 while (WiFi.status() != WL_CONNECTED) {
     delay(1000);
     Serial.println(".");
 }
 Serial.println("Connected to the WiFi network");

 // 先配置TLS客户端参数
 espClient.setCACert(root_ca);
 espClient.setInsecure(); // 仅IP直连自签名证书场景使用,域名连接时删除该行
 // 配置完TLS再绑定MQTT服务器
 client.setServer(mqtt_broker, mqtt_port);

 while (!client.connected()) {
     String client_id = "wokwi-test";
     Serial.printf("Client %s connecting to MQTT broker\n", client_id.c_str());
     if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
         Serial.println("MQTT broker connected");
     } else {
         Serial.print("Connect failed, state code: ");
         Serial.println(client.state());
         delay(2000);
     }
 }
}

void loop() {
  client.loop(); // 必须调用,否则MQTT连接会自动断开
}

额外说明:Wokwi仿真环境默认会同步系统时间,不需要额外编写NTP对时逻辑,不会出现TLS证书时间校验失败的问题。如果换实体硬件测试,需要先联网同步时间再做MQTT连接。

内容的提问来源于stack exchange,提问作者Adrian Pilikser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 23:51:36