wolfSSL/wolfMQTT
GitHub: wolfSSL/wolfMQTT
一款用 C 语言编写的轻量级 MQTT 客户端及 Broker 实现,专为嵌入式系统设计并原生支持 TLS 1.3 安全通信。
Stars: 581 | Forks: 167
# wolfMQTT
这是一个用 C 语言编写的 MQTT 客户端实现,专为嵌入式用途设计,通过 wolfSSL 库支持 SSL/TLS。该库从头开始构建,具有多平台、节省空间和可扩展的特点。它与 wolfSSL 集成以提供 TLS 支持。
有关 wolfMQTT 的详细信息,请参阅 [wolfMQTT 手册](https://www.wolfssl.com/documentation/manuals/wolfmqtt/wolfMQTT-Manual.pdf)。
## 构建
### Mac/Linux/Unix
1. `./autogen.sh`(如果是从 GitHub 克隆的)
2. `./configure`(要查看构建选项列表,请使用 `./configure --help`)
3. `make`
4. `sudo make install`
注意:
* 如果最近安装了 `wolfssl`,请运行 `sudo ldconfig` 以更新链接器缓存。
* 可以使用 `--enable-debug` 或 `--enable-debug=verbose`(用于额外日志记录)来启用调试消息。
* 要查看构建选项列表,请运行 `./configure --help`。
* 构建选项生成在以下文件中:`wolfmqtt/options.h`。
### Windows Visual Studio
要在 Visual Studio 中构建支持 TLS 的 wolfMQTT:
1. 打开 `/wolfssl64.sln`。
2. 为您的 Visual Studio 版本重新设定目标(右键单击解决方案并选择 `Retarget solution`)。
3. 确保选中了 `Debug DLL` 或 `Release DLL` 配置。记录下您构建的是 32 位 `x86` 还是 64 位 `x64`。
4. 构建 wolfSSL 解决方案。
5. 将 `wolfssl.lib` 和 `wolfssl.dll` 文件复制到 ``。
* 对于 `x86` 的 `DLL Debug`,文件位于:`DLL Debug`。
* 对于 `x86` 的 `DLL Release`,文件位于:`DLL Release`。
* 对于 `x64` 的 `DLL Debug`,文件位于:`x64/DLL Debug`。
* 对于 `x64` 的 `DLL Release`,文件位于:`x64/DLL Release`。
6. 打开 `/wolfmqtt.sln` 解决方案。
7. 确保您选择了与上述 wolfSSL 中使用的相同架构(`x86` 或 `x64`)。
8. 默认情况下,wolfssl 头文件的包含路径是 `./../wolfssl/`。如果您的 wolfssl 根目录位置不同,可以进入项目设置并在 `C/C++` -> `General` -> `Additional Include Directories` 中进行调整。
9. 使用 `wolfmqtt/vs_settings.h` 配置您的 Visual Studio 构建设置。
10. 构建 wolfMQTT 解决方案。
### CMake
CMake 支持在许多环境中编译,包括 Visual Studio(如果已安装 CMake 支持)。以下命令可以在 `Developer Command Prompt` 中运行。
```
mkdir build
cd build
# 使用已安装的 wolfSSL 位置(库和头文件)
cmake .. -DWITH_WOLFSSL=/prefix/to/wolfssl/install/
# 或使用 wolfSSL 源码树
cmake .. -DWITH_WOLFSSL_TREE=/path/to/wolfssl/
# 构建
cmake --build .
```
### vcpkg
您可以使用 [vcpkg](https://github.com/Microsoft/vcpkg) 下载并安装 wolfMQTT:
```
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
OR for Windows
bootstrap-vcpkg.bat
./vcpkg integrate install
./vcpkg install wolfmqtt
```
vcpkg 中的 wolfMQTT 端口由 wolfSSL 保持更新。
我们还有用于 wolftpm、wolfssl 和 curl 的 vcpkg 端口。
### Arduino
参见 [IDE/ARDUINO.README.md](IDE/ARDUINO.README.md) 中的 `README.md`
### MinGW
```
export PATH="/opt/mingw-w32-bin_i686-darwin/bin:$PATH"
export PREFIX=$PWD/build
# wolfSSL
cd wolfssl
./configure --host=i686 CC=i686-w64-mingw32-gcc LD=i686-w64-mingw32-ld CFLAGS="-DWIN32 -DMINGW -D_WIN32_WINNT=0x0600" LIBS="-lws2_32 -L$PREFIX/lib -lwolfssl" --prefix=$PREFIX
make
make install
# wolfMQTT
cd ../wolfmqtt
./configure --host=i686 CC=i686-w64-mingw32-gcc LD=i686-w64-mingw32-ld CFLAGS="-DWIN32 -DMINGW -D_WIN32_WINNT=0x0600 -DBUILDING_WOLFMQTT -I$PREFIX/include" LDFLAGS="-lws2_32 -L$PREFIX/lib -lwolfssl" --prefix=$PREFIX --disable-examples
make
```
### Zephyr RTOS
在 [zephyr](zephyr) 目录中提供了对 Zephyr 的支持。有关如何为 Zephyr 构建的说明,请参阅 [README.md](zephyr/README.md)。
## 架构
该库包含三个组件。
### 1. mqtt_client
这是 MQTT 客户端顶级应用接口所在的位置。
* `int MqttClient_Init(MqttClient *client, MqttNet *net, MqttMsgCb msg_cb, byte *tx_buf, int tx_buf_len, byte *rx_buf, int rx_buf_len, int cmd_timeout_ms);`
这些 API 在 `MqttNet.read` 上阻塞,直到出错/超时(`cmd_timeout_ms`):
* `int MqttClient_Connect(MqttClient *client, MqttConnect *connect);`
* `int MqttClient_Publish(MqttClient *client, MqttPublish *publish);`
* `int MqttClient_Subscribe(MqttClient *client, MqttSubscribe *subscribe);`
* `int MqttClient_Unsubscribe(MqttClient *client, MqttUnsubscribe *unsubscribe);`
* `int MqttClient_Ping(MqttClient *client);`
* `int MqttClient_Disconnect(MqttClient *client);`
此函数阻塞等待新的发布消息到达,最长持续时间为 `timeout_ms`。
* `int MqttClient_WaitMessage(MqttClient *client, MqttMessage *message, int timeout_ms);`
这些是网络连接/断开接口,它们封装了 MqttNet 回调并处理 WolfSSL TLS:
* `int MqttClient_NetConnect(MqttClient *client, const char* host, word16 port, int timeout_ms, int use_tls, MqttTlsCb cb);`
* `int MqttClient_NetDisconnect(MqttClient *client);`
辅助函数:
* `const char* MqttClient_ReturnCodeToString(int return_code);`
### 2. mqtt_packet
这是处理所有数据包编码/解码的地方。
头文件包含以下 MQTT 数据包结构:
* Connect:`MqttConnect`
* Publish / Message:`MqttPublish` / `MqttMessage`(它们是相同的)
* Subscribe:`MqttSubscribe`
* Unsubscribe:`MqttUnsubscribe`
### 3. mqtt_socket
这是传输套接字可选地封装 TLS 并使用 `MqttNet` 回调进行平台特定网络处理的地方。
头文件包含用于网络回调和上下文的 MQTT 网络结构 `MqttNet`。
## 实现
以下是创建您自己的实现的步骤。
1. 为 Connect、Read、Write 和 Disconnect 创建网络回调函数。参见 `examples/mqttnet.c` 和 `examples/mqttnet.h`。
2. 在 `MqttNet` 结构中定义回调函数和上下文。
3. 调用 `MqttClient_Init`,传入 `MqttClient` 结构指针、`MqttNet` 结构指针、`MqttMsgCb` 函数指针、具有最大长度的 TX/RX 缓冲区以及命令超时时间。
4. 调用 `MqttClient_NetConnect` 以通过网络连接到代理(broker)。如果 `use_tls` 为非零值,则它将执行 TLS 连接。应该为 wolfSSL 证书配置定义 TLS 回调 `MqttTlsCb`。
5. 调用 `MqttClient_Connect`,传入指向 `MqttConnect` 结构的指针,以发送 MQTT 连接命令并等待 Connect Ack。
6. 调用 `MqttClient_Subscribe`,传入指向 `MqttSubscribe` 结构的指针,以发送 MQTT Subscribe 命令并等待 Subscribe Ack(取决于 QoS 级别)。
7. 调用 `MqttClient_WaitMessage`,传入指向 `MqttMessage` 的指针,以等待传入的 MQTT Publish 消息。
## 示例
### Client 示例
MQTT 客户端示例位于 `/examples/mqttclient/`。此示例演练了许多公开的 API,并打印订阅主题 "wolfMQTT/example/testTopic" 的任何传入发布消息。此客户端包含许多 MQTTv5 功能的示例,包括属性回调和服务器分配的客户端 ID。mqttclient 示例是您的 MQTT 应用程序的一个很好的起始模板。
### Simple Standalone Client 示例
MQTT 客户端示例位于 `/examples/mqttsimple/`。此示例演示了使用标准 BSD 套接字的独立客户端。这需要定义 `HAVE_SOCKET`,该定义来自 ./configure 生成的 `wolfmqtt/config.h` 文件。所有参数都是在 `/examples/mqttsimple/mqttsimple.c` 顶部定义的构建时宏。
### Non-Blocking Client 示例
MQTT 客户端示例位于 `/examples/nbclient/`。此示例使用非阻塞 I/O 进行消息交换。必须使用 `--enable-nonblock` 选项配置 wolfMQTT 库(或使用 `WOLFMQTT_NONBLOCK` 构建)。
### Firmware 示例
MQTT 固件更新位于 `/examples/firmware/`。此示例包含两部分。第一部分称为 "fwpush",它签名并发布固件镜像。第二部分称为 "fwclient",它接收固件镜像并验证签名。此示例在主题 "wolfMQTT/example/firmware" 上发布消息。"fwpush" 应用程序是使用发布回调发送负载数据的示例。
### Azure IoT Hub 示例
我们在 Azure 服务器上设置了一个 wolfMQTT IoT Hub 用于测试。我们添加了一个名为 `demoDevice` 的设备,您可以连接并向其发布。该示例演示了 SasToken 的创建,它被用作 MQTT 连接数据包的密码。它还显示了用于发布事件和侦听 `devicebound` 消息的主题名称。此示例仅在设置了 `ENABLE_MQTT_TLS` 且存在 wolfSSL 库时才有效,因为它需要 Base64 Encode/Decode 和 HMAC-SHA256。注意:wolfSSL 库必须使用 `./configure --enable-base64encode` 或 `#define WOLFSSL_BASE64_ENCODE` 构建。`wc_GetTime` API 是在 3.9.1 版本中添加的,如果不存在,您需要实现自己的版本来获取当前 UTC 秒数或更新您的 wolfSSL 库。
**注意** Azure 代理仅支持 MQTT v3.1.1
### AWS IoT 示例
我们设置了一个 AWS IoT 端点和测试设备证书用于测试。AWS 服务器使用 TLS 客户端证书进行身份验证。该示例位于 `/examples/aws/`。该示例订阅 `$aws/things/"AWSIOT_DEVICE_ID"/shadow/update/delta` 并发布到 `$aws/things/"AWSIOT_DEVICE_ID"/shadow/update`。
**注意** AWS 代理仅支持 MQTT v3.1.1
### Watson IoT 示例
此示例使 wolfMQTT 客户端能够连接到 IBM Watson Internet of Things (WIOT) 平台。WIOT 平台有一个名为 "Quickstart" 的有限测试代理,允许非安全连接来演练该组件。该示例位于 `/examples/wiot/`。启用 MQTT v5 支持后可正常工作。
**注意** WIOT 平台将于 2023 年 12 月停用。该演示对于 IBM Watson IOT 的用户可能仍然有用。
### MQTT-SN 示例
传感器网络客户端实现了用于低带宽网络的 MQTT-SN 协议。与 MQTT 相比存在若干差异,包括在订阅和发布期间使用两字节的 Topic ID 而不是完整主题的能力。SN 客户端需要一个 MQTT-SN 网关。该网关充当 SN 客户端和代理之间的中介。此客户端是使用 Eclipse Paho MQTT-SN 网关进行测试的,该网关默认连接到公共 Eclipse 代理,就像我们的 wolfMQTT 客户端示例一样。必须将网关的地址配置为主机。该示例位于 `/examples/sn-client/`。
关于 MQTT-SN 示例的更多信息,请参阅 [examples/sn-client/README.md](examples/sn-client/README.md)
### Multithread 示例
此示例演练了客户端库的多线程功能。客户端实现了两个任务:一个向代理发布;另一个等待来自代理的消息。发布线程被创建了 `NUM_PUB_TASKS` 次(默认为 5),并向代理发送唯一的消息。此功能使用 `--enable-mt` 配置选项启用。该示例位于 `/examples/multithread/`。
多线程功能也可以与非阻塞套接字 (--enable-nonblock) 一起使用。
如果您在 Linux 上遇到线程同步问题,请考虑不使用条件信号 (`WOLFMQTT_NO_COND_SIGNAL`)。
### 原子发布和订阅示例
在 `examples/pub-sub` 文件夹中,有两个简单的客户端示例:
* mqtt-pub - 发布到某个主题
* mqtt-sub - 订阅某个主题并等待消息
这些示例对于快速测试或脚本编写非常有用。
## 示例选项
命令行示例可以使用可选参数执行。要查看可用参数的列表,请添加 `-?`
```
./examples/mqttclient/mqttclient -?
mqttclient:
-? Help, print this usage
-h Host to connect to, default: test.mosquitto.org
-p Port to connect on, default: Normal 1883, TLS 8883
-t Enable TLS
-A Load CA (validate peer)
-K Use private key (for TLS mutual auth)
-c Use certificate (for TLS mutual auth)
-S Use Host Name Indication, blank defaults to host
-q Qos Level 0-2, default: 0
-s Disable clean session connect flag
-k Keep alive seconds, default: 60
-i Client Id, default: WolfMQTTClient
-l Enable LWT (Last Will and Testament)
-u Username
-w Password
-m Message, default: test
-n Topic name, default: wolfMQTT/example/testTopic
-r Set Retain flag on publish message
-C Command Timeout, default: 30000ms
-P Max packet size the client will accept, default: 1048576
-T Test mode
-f Use file contents for publish
```
可用选项因库配置而异。
## Broker 兼容性
wolfMQTT 客户端库已在以下代理(broker)上进行了测试:
* Adafruit IO by Adafruit
* AWS by Amazon
* Azure by Microsoft
* flespi by Gurtam
* HiveMQ and HiveMQ Cloud by HiveMQ GmbH
* IBM WIoTP Message Gateway by IBM
* Mosquitto by Eclipse
* Paho MQTT-SN Gateway by Eclipse
* VerneMQ by VerneMQ/Erlio
* EMQX broker
## 规范支持
### MQTT v3.1.1 规范支持
最初支持的版本,具有对所有功能和数据包类型的完整规范支持,例如:
* QoS 0-2
* Last Will and Testament (LWT)
* 客户端示例:AWS、Azure IoT、固件更新、非阻塞和通用示例。
### MQTT v5.0 规范支持
使用 `--enable-v5` 选项配置时,wolfMQTT 客户端支持连接到启用了 v5 的代理。
wolfMQTT 客户端支持以下 v5.0 规范:
* AUTH 数据包
* 用户属性
* 服务器连接 ACK 属性
* 发布的格式和内容类型
* 服务器断开连接
* 原因代码和字符串
* 最大数据包大小
* 服务器分配的客户端标识符
* 订阅 ID
* 主题别名
启用了 v5 的 wolfMQTT 客户端已在以下 MQTT v5 代理上进行了测试:
* Mosquitto
** 本地运行。
** `./examples/mqttclient/mqttclient -h localhost`
* Flespi
** 需要与帐户绑定的令牌,该令牌每小时重新生成。
** `./examples/mqttclient/mqttclient -h "mqtt.flespi.io" -u ""`
* VerneMQ MQTTv5 预览版
** 本地运行。
** `./examples/mqttclient/mqttclient -h localhost`
* HiveMQ 4.0.0 EAP
** 本地运行。
** `./examples/mqttclient/mqttclient -h localhost`
* HiveMQ Cloud
** `./examples/mqttclient/mqttclient -h 833f87e253304692bd2b911f0c18dba1.s1.eu.hivemq.cloud -t -S -u wolf1 -w NEZjcm7i8eRjFKF -p 8883`
* EMQX broker
** `./examples/mqttclient/mqttclient -h "broker.emqx.io"`
默认情况下,属性是从本地堆栈(大小为 `MQTT_MAX_PROPS`)分配的。定义 `WOLFMQTT_DYN_PROP` 以使用 malloc 进行属性分配。
### MQTT 传感器网络 (MQTT-SN) 规范支持
wolfMQTT SN 客户端实现基于 OASIS MQTT-SN v1.2 规范。SN API 使用 `--enable-sn` 选项配置。传感器网络 API 有一个单独的 API,均以 "SN_" 前缀开头。wolfMQTT SN 客户端通过 UDP 运行,这与使用 TCP 的 wolfMQTT 客户端不同。wolfMQTT SN 客户端支持以下功能:
* 注册
* Will 主题和消息设置
* Will 主题和消息更新
* 所有 QoS 级别
* 可变大小的数据包长度字段
不支持的功能:
* 未实现自动网关发现
* 多网关处理
SN 客户端是使用在本地和单独网络节点上运行的 Eclipse Paho MQTT-SN 网关 进行测试的。构建和运行网关的说明位于项目 README 中。
## Post-Quantum MQTT 支持
最近,OpenQuantumSafe 项目已将其 OpenSSL 分支与 mosquito MQTT 代理集成。您现在可以使用 wolfSSL 构建 wolfMQTT,并使用它发布到 mosquito MQTT 代理。目前,wolfMQTT 支持 `ML_KEM_768` 和 `SecP384r1MLKEM768` 组以及 ML-DSA-65 用于 TLS 1.3 中的身份验证。这适用于 Linux。
### Post-Quantum Mosquito MQTT Broker 和订阅器入门
首先,您可以使用位于 https://github.com/open-quantum-safe/oqs-demos/ 的 oqs-demos 仓库。
按照 README.md 和 USAGE.md 中的所有说明进行操作。这允许您创建 docker 镜像和 docker 网络。然后您将运行代理、订阅者和发布者。最后,发布者将退出,代理和订阅者将保持活动状态。
注意:不要停止代理和订阅者实例。
您需要进入 docker 实例并将以下文件获取到本地计算机上:
- /test/cert/CA.crt
- /test/cert/publisher.crt
- /test/cert/publisher.key
发布者退出后,可以执行以下命令:
sudo docker run --network mosquitto-test --ip 174.18.0.4 -it --rm --name oqs-mosquitto-publisher -e "BROKER_IP=174.18.0.2" -e "PUB_IP=174.18.0.4" oqs-mosquitto bash
这会在 docker 容器“内部”打开一个 bash shell。您将看到用于执行发布者的 shell 脚本。这包括生成密钥和证书的命令。执行它们,然后使用 cat 显示它们,然后将它们复制并粘贴到 wolfMQTT 根目录中。
### 构建和运行 Post-Quantum wolfMQTT 发布者
像这样构建和安装 wolfSSL:
```
./autogen.sh (if obtained from github)
./configure --enable-dilithium --enable-mlkem
make all
make check
```
构建 wolfMQTT 不需要特殊标志。只需执行以下操作:
```
./autogen.sh (if obtained from github)
./configure
make all
make check
```
注意:无需安装 wolfmqtt。
由于代理和订阅者仍在运行,您可以通过执行以下操作使用 `mqttclient` 在 TLS 1.3 中使用后量子算法进行发布:
```
./examples/mqttclient/mqttclient -T -h 174.18.0.2 -p 8883 -t -A CA.crt -K publisher.key -c publisher.crt -m "Hello from post-quantum wolfMQTT" -n test/sensor1 -Q SecP384r1MLKEM768
```
恭喜!您刚刚使用 TLS 1.3 以及与 P-384 曲线上的 ECDHE 混合的 ML-KEM-768 和 ML-DSA-65 签名方案发布了 MQTT 消息。要仅使用 ML-KEM-768,请将 `SecP384r1MLKEM768` 替换为 `ML_KEM_768`。此外,您还展示了与 liboqs、liboqs-provider、openssl3 和 mosquitto 的互操作性。
测试的最新版本组合:
- wolfSSL: v5.8.2-stable
- wolfMQTT: v1.20.0
- oqs-demos: commit 29d4dccbd547a62e8ba77d3fef1af5d6f8625d60
## Curl Easy Socket 支持
wolfMQTT 现在支持使用 libcurl 的 easy socket 接口作为后端。
启用后,wolfMQTT 将使用 libcurl API 作为套接字后端,
并且 libcurl 将使用 wolfSSL 协商 TLS。
可以使用 `--enable-curl` 启用此功能。
目前,wolfMQTT 的 libcurl 选项支持 TLS 和 mTLS,但不支持 Post-Quantum TLS。
### 如何将 libcurl 与 wolfMQTT 一起使用
要将 wolfMQTT 与 libcurl 和 wolfSSL 一起使用:
- 使用 `--enable-curl` 构建 wolfssl 并安装到 `/usr/local`。
- 使用 `--with-wolfssl` 构建 libcurl 并安装到 `/usr/local`。
最后,使用 `--enable-curl` 构建 wolfMQTT。
### 支持的构建选项
`--enable-curl` 选项适用于以下组合:
- `--enable-mt`
- `--enable-nonblock`
- `--enable-tls`(默认启用)
- `--enable-timeout`(默认启用)
但是,`--enable-curl` 与以下选项不兼容且不受支持:
- `--enable-all`
- `--enable-sn`
## Stress 构建选项
为了简化测试,添加了一个 stress 构建选项 `--enable-stress=[args]`。
Stress 选项启用多线程和非阻塞,并添加以下定义:
`TEST_NONBLOCK`、`NUM_PUB_TASKS` 和 `NUM_PUB_PER_TASK`。
用法示例:
- `--enable-stress`:使用默认选项进行压力测试。
- `--enable-stress=t7,p8`:使用 7 个线程和每个线程 8 次发布进行压力测试。
- `--enable-stress=t7,p8 --enable-curl`:与上述相同,但使用 curl 后端。
注意:启用 stress 后,多线程示例仅限 localhost,
不会连接到远程服务器。此外,测试 `scripts/stress.test`
被添加到 `make check` 中,并且所有其他测试都被禁用。
## Broker
wolfMQTT 包含一个轻量级 MQTT 代理实现,适用于嵌入式和资源受限的环境。它支持 MQTT v3.1.1 和 v5.0 客户端,并通过 wolfSSL 提供可选的 TLS。
### 功能
* QoS 0、QoS 1 和 QoS 2 发布/订阅(完整的 QoS 2 流程,包含 PUBREC/PUBREL/PUBCOMP)
* Retained messages
* Last Will and Testament (LWT) 以及 v5 Will Delay Interval
* 通配符订阅(`+` 和 `#`)
* 用户名/密码认证
* TLS 支持(需要带有 `--enable-tls` 的 wolfSSL)
* Clean session 处理及订阅持久化
* Keep-alive 监控及自动客户端断开连接
* 唯一客户端 ID 强制执行(现有会话接管)
* 静态内存模式(`WOLFMQTT_STATIC_MEMORY`)用于零 malloc 操作
### 构建
使用 autotools:
```
./configure --enable-broker
make
```
使用 CMake:
```
cmake .. -DWOLFMQTT_BROKER=yes
cmake --build .
```
### 运行
```
./src/mqtt_broker -p 1883
```
对于 TLS:
```
./src/mqtt_broker -p 8883 -t -A ca-cert.pem -K server-key.pem -c server-cert.pem
```
运行 `./src/mqtt_broker -h` 以查看所有可用选项。
### 功能构建选项
默认情况下,所有代理功能均已启用。可以在构建时禁用单个功能,以减少受限平台上的代码和内存占用。
| 功能 | Autotools | CMake | Define |
|---|---|---|---|
| Retained messages | `--disable-broker-retained` | `-DWOLFMQTT_BROKER_RETAINED=no` | `WOLFMQTT_BROKER_NO_RETAINED` |
| Last Will and Testament | `--disable-broker-will` | `-DWOLFMQTT_BROKER_WILL=no` | `WOLFMQTT_BROKER_NO_WILL` |
| 通配符订阅 | `--disable-broker-wildcards` | `-DWOLFMQTT_BROKER_WILDCARDS=no` | `WOLFMQTT_BROKER_NO_WILDCARDS` |
| 认证 | `--disable-broker-auth` | `-DWOLFMQTT_BROKER_AUTH=no` | `WOLFMQTT_BROKER_NO_AUTH` |
### 静态内存模式
使用 `WOLFMQTT_STATIC_MEMORY` 构建时,代理使用固定大小的数组而不是动态分配。可以通过编译时宏调整缓冲区大小和限制:
| Macro | 默认值 | 描述 |
|---|---|---|
| `BROKER_MAX_CLIENTS` | 8 | 最大并发客户端连接数 |
| `BROKER_MAX_SUBS` | 32 | 最大总订阅数 |
| `BROKER_MAX_RETAINED` | 16 | 最大 retained messages 数 |
| `BROKER_RX_BUF_SZ` | 4096 | 每个客户端的接收缓冲区大小 |
| `BROKER_TX_BUF_SZ` | 4096 | 每个客户端的发送缓冲区大小 |
| `BROKER_MAX_PAYLOAD_LEN` | 4096 | 最大 retained message 负载 |
| `BROKER_MAX_WILL_PAYLOAD_LEN` | 256 | 最大 LWT 负载大小 |
## WebSocket 支持
wolfMQTT 支持 MQTT over WebSockets,允许客户端通过 WebSocket 端点连接到 MQTT 代理。这对于传统 MQTT 端口可能被阻止的环境或与 Web 应用程序集成非常有用。
支持标准 WebSockets 和安全 WebSockets (WSS)。
### 使用 WebSocket 支持构建
要使用 WebSocket 支持构建 wolfMQTT:
1. 安装 libwebsockets 开发库:
```
# 在 Debian/Ubuntu 上
sudo apt-get install libwebsockets-dev
# 在 macOS 上使用 Homebrew
brew install libwebsockets
```
2. 使用 WebSocket 支持配置 wolfMQTT:
```
./configure --enable-websocket
```
注意:如果遇到任何冲突,您也可以使用 `--enable-opensslcoexist` 构建 wolfSSL(以支持在同一构建中同时使用 OpenSSL 和 wolfSSL)。
3. 像往常一样构建:
```
make
```
### WebSocket 示例
WebSocket 客户端示例位于 `/examples/websocket/`。此示例演示如何使用 WebSockets 连接到 MQTT 代理。该示例订阅主题 "test/topic" 并等待传入消息。
要运行该示例:
```
./examples/websocket/websocket_client [-h host] [-p port] [-t]
```
默认情况下,它连接到端口 `8080` 上的 `localhost`。
#### 安全 WebSocket 支持
wolfMQTT 还支持安全 WebSockets (WSS),它们使用 TLS 加密 WebSocket 连接。
要使用安全 WebSockets:
* 确保您在构建 wolfMQTT 时同时启用了 WebSocket 和 TLS 支持:
```
./configure --enable-websocket --enable-tls
```
* 运行启用 TLS 的 WebSocket 示例:
```
./examples/websocket/websocket_client -t -p 8081
```
* 您还可以指定用于 TLS 验证的 CA 证书:
```
./examples/websocket/websocket_client -t -p 8081 -A /path/to/ca-cert.pem
```
* 对于双向 TLS 身份验证,您可以指定客户端证书和密钥:
```
./examples/websocket/websocket_client -t -p 8081 -A /path/to/ca-cert.pem --cert /path/to/client-cert.pem --key /path/to/client-key.pem
```
* 您还可以使用来自 wolfSSL 的 TLS 支持从源代码构建 libwebsockets 库:
```
cmake .. -DLWS_WITH_WOLFSSL=1 -DLWS_WOLFSSL_INCLUDE_DIRS=/usr/local/include/wolfssl -DLWS_WOLFSSL_LIBRARIES=/usr/local/lib/libwolfssl.so -DLWS_WITH_EXTERNAL_POLL=1 -DCMAKE_BUILD_TYPE=DEBUG ..
```
此选项要求使用 `./configure --enable-libwebsockets --enable-alpn` 构建 wolfSSL 并安装到 `/usr/local`。
### Broker 配置
要使用 WebSocket 示例,您的 MQTT 代理必须配置为支持 WebSockets。对于 Mosquitto,请将以下内容添加到您的 `mosquitto.conf`:
```
# WebSocket 设置
listener 8080
protocol websockets
```
对于安全 WebSocket 支持,请添加:
```
# Secure WebSocket
listener 8081
protocol websockets
cafile /ca-cert.pem
# PEM 编码服务器证书路径。
certfile /server-cert.pem
# PEM 编码密钥文件路径。
keyfile /server-key.pem
```
然后使用此配置重新启动 Mosquitto:
```
mosquitto -c mosquitto.conf
```
websocket 文件夹中有一个示例 mosquitto 配置文件:
`$ mosquitto -c examples/websocket/mosq_ws.conf`
您还可以构建 mosquitto 代理以使用 wolfSSL 进行 TLS 连接:
https://github.com/wolfSSL/osp/tree/master/mosquitto
### 现细节
WebSocket 实现使用 libwebsockets 作为后端,并为 MQTT 客户端提供自定义网络回调:
- `NetWebsocket_Connect`:建立到代理的 WebSocket 连接
- `NetWebsocket_Read`:从 WebSocket 连接读取数据
- `NetWebsocket_Write`:将数据写入 WebSocket 连接
- `NetWebsocket_Disconnect`:关闭 WebSocket 连接
该示例还实现了一种 ping 机制来保持 WebSocket 连接处于活动状态,每 30 秒向代理发送一次 ping。
### 使用公共代理进行测试
您可以针对支持 websockets 的公共代理测试 wolfMQTT 客户端:
* Mosquitto 未加密
`./examples/websocket/websocket_client -h test.mosquitto.org -p8080`
* Mosquitto 安全 websocket
`./examples/websocket/websocket_client -h test.mosquitto.org -p8081 -t`
* HiveMQ 未加密
`./examples/websocket/websocket_client -h broker.hivemq.com -p8000`
* HiveMQ 安全 websockets
`./examples/websocket/websocket_client -h broker.hivemq.com -p8884 -t`
标签:Bash脚本, C库, IoT, LangChain, Mac, MQTT客户端, SSL/TLS, TLS 1.3, wolfMQTT, wolfSSL, 中间件, 客户端加密, 嵌入式系统, 开源库, 搜索引擎爬虫, 消息队列, 物联网, 网络安全, 轻量级, 通信协议, 遥测, 隐私保护