
背景
当前各大云服务商提供的MQTT服务(或者Websockets)基本都推荐使用TLS/SSL加密的方式连接,一般情况下ESP32所采用的Arduino MQTT 库是PubSubClient,当我们遇到需要加密连接的时候,可能会去寻找其他的支持SSL连接的库,但是使用下来发现无论从易用性、文档的完善性还是其他方面,都不如PubSubClient。因此,本文的重点就变成了如何使用PubSunClient连接加密的MQTT服务
准备工作
- ESP32开发板
- 电脑
- 路由器
- 支持TLS/SSL加密的MQTT服务器
- Arduino IDE / PlatformIO (VsCode 插件)
具体流程
首先我们先看一下一般情况下,使用PubSubClient连接非加密的MQTT服务器相关的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include <WiFi.h> #include <PubSubClient.h>
const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; const char* mqtt_server = "mqtt.example.com"; const int mqtt_port = 1883; const char* mqtt_user = "your_USERNAME"; const char* mqtt_password = "your_PASSWORD";
WiFiClient espClient; PubSubClient client(espClient);
void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } }
void loop() { if (!client.connected()) { Serial.println("Connecting to MQTT..."); if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("Connected to MQTT server"); } else { Serial.print("Failed to connect, state: "); Serial.println(client.state()); delay(2000); } } } ```
我们可以看到,主要分为几个部分,首先是连接WiFi,之后初始化MQTT服务器,最后是一个循环,用于保持连接状态。那么如果我们需要连接加密的MQTT服务器,我们需要做哪些修改呢?
首先,我们需要修改WiFi.begin函数,使其支持SSL/TLS加密,代码如下:
```cpp
#include <WiFiClientSecure.h>
#include <time.h>
const char* mqtt_ca= \ "-----BEGIN CERTIFICATE-----\n" \ "MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n" \ "................................................................\n" \ "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n" \ "-----END CERTIFICATE-----\n";
configTime(0, 0, "ntp1.aliyun.com");
WiFiClientSecure wifiSecureClient;
wifiSecureClient.setCACert(mqtt_ca);
|
接下来的步骤与之前的代码相同,我们可以看到,上面的代码中主要修改有两处,第一是需要校准时间,第二是需要加载证书。只需要简单的修改就可以实现加密连接了。以下是完整的加密连接代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <WiFi.h> #include <PubSubClient.h> #include <WiFiClientSecure.h> #include <time.h> const char* ssid = "your_SSID"; const char* password = "your_PASSWORD"; const char* mqtt_server = "mqtt.example.com"; const int mqtt_port = 8883; const char* mqtt_user = "your_USERNAME"; const char* mqtt_password = "your_PASSWORD";
WiFiClientSecure wifiSecureClient;
const char* mqtt_ca= \ "-----BEGIN CERTIFICATE-----\n" \ "MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n" \ "................................................................\n" \ "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n" \ "-----END CERTIFICATE-----\n";
PubSubClient client(wifiSecureClient);
void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status()!= WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } wifiSecureClient.setCACert(mqtt_ca); configTime(0, 0, "ntp1.aliyun.com"); }
void loop() { if (!client.connected()) { Serial.println("Connecting to MQTT..."); if (client.connect("ESP32Client", mqtt_user, mqtt_password)) { Serial.println("Connected to MQTT server"); } else { Serial.print("Failed to connect, state: "); Serial.println(client.state()); delay(2000); } } }
|
——Wicos 2025-05-28