eclipse-paho/paho.mqtt.c
GitHub: eclipse-paho/paho.mqtt.c
Eclipse Paho 出品的 MQTT 协议 C 语言客户端库,支持同步/异步模型和 SSL/TLS 加密,适用于跨平台 IoT 设备与后端服务的轻量级消息通信集成。
Stars: 2301 | Forks: 1173
[](https://travis-ci.org/eclipse/paho.mqtt.c)
[](https://lgtm.com/projects/g/eclipse/paho.mqtt.c/alerts/)
[](https://scan.coverity.com/projects/paho-c)
# Eclipse Paho MQTT 协议 C 客户端库
此仓库包含 [Eclipse Paho](http://eclipse.org/paho) MQTT C 客户端库的源代码。
此代码构建的库使应用程序能够连接到 [MQTT](http://mqtt.org) 代理以发布消息,并订阅主题以及接收已发布的消息。
支持同步和各种异步编程模型。
## 关于 MQTT 的信息
* [MQTT 网站](http://mqtt.org)
* [MQTT 3.1.1 标准](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html)
* [MQTT 5.0 标准](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html)
* [HiveMQ 的 MQTT 介绍](https://www.hivemq.com/mqtt/)
* [OASIS 的 MQTT 介绍演示](https://www.oasis-open.org/committees/download.php/49205/MQTT-OASIS-Webinar.pdf)
## 库
Paho C 客户端包含四个变体库,可为共享或静态库:
* paho-mqtt3a - 异步 (MQTTAsync)
* paho-mqtt3as - 支持 SSL/TLS 的异步 (MQTTAsync)
* paho-mqtt3c - “经典” / 同步 (MQTTClient)
* paho-mqtt3cs - 支持 SSL/TLS 的“经典” / 同步 (MQTTClient)
[结合上下文,关于使用哪个 Paho C API 及其历史背景](https://modelbasedtesting.co.uk/2013/10/13/which-paho-mqtt-c-api-to-use-and-some-history/)
## 用法和 API
详细的 API 文档[可在线获取](https://eclipse-paho.github.io/paho.mqtt.c/MQTTClient/html/)。通过构建 ``doc`` 目录中的 Doxygen 文档也可以获取该文档。
Doxygen 文档中提供了示例,也可在 `src/samples` 中找到以供参考。这些示例包括:
- *paho_c_pub.c* 和 *paho_c_sub.c:* 用于发布和订阅的命令行工具,-h 将提供帮助
- *paho_cs_pub.c* 和 *paho_cs_sub.c:* 使用 MQTTClient 进行发布和订阅的命令行工具
- *MQTTClient_publish.c、MQTTClient_subscribe.c* 和 *MQTTClient_publish_async.c:* MQTTClient 简单代码示例
- *MQTTAsync_publish.c* 和 *MQTTAsync_subscribe.c:* MQTTAsync 简单代码示例
一些可能有用的博客文章:
- [Paho 客户端 MQTT 5.0 支持及命令行工具](https://modelbasedtesting.co.uk/2018/08/08/paho-c-client-mqtt-5-0-and-command-line-utilities/)
- [MQTT、QoS 与持久化](https://modelbasedtesting.co.uk/2013/11/24/mqtt-qos-and-persistence/)
- [关于 MQTT 5.0 的故事](https://modelbasedtesting.co.uk/2018/04/09/a-story-of-mqtt-5-0/)
[我做过的各种关于 MQTT 和 MQTT-SN 的演讲。](https://modelbasedtesting.co.uk/talks-ive-given/)
### 支持的网络协议
该库支持使用 TCP、SSL/TLS、Unix 域套接字和 websockets(安全和非安全)连接到 MQTT 服务器。客户端通过使用连接选项中提供的 URI 进行选择。可以按如下方式指定:
```
"mqtt://:" - TCP, unsecure
"tcp://:" (same)
"mqtts://:" - SSL/TLS
"ssl://:" (same)
"unix:///path/to/socket - UNIX-domain socket (*nix systems only)
"ws://:[/path]" - Websockets, unsecure
"wss://:[/path]" - Websockets, secure
```
"mqtt://" 和 "tcp://" 前缀是相同的。它们表示通过 TCP 的非安全连接。"mqtt://" 变体对该库来说是新增的,但在不同的 MQTT 库中正变得越来越普遍。
同样,"mqtts://" 和 "ssl://" 前缀也是相同的。它们指定了通过 SSL/TLS 套接字的安全连接。使用任何安全连接选项都需要您使用 `PAHO_WITH_SSL=TRUE` CMake 选项编译库以包含 OpenSSL。此外,在连接到代理时,您_必须_指定 `ssl_options` - 即在调用 `connect()` 时,您必须将 `ssl_options` 的实例添加到 `connect_options` 中。
使用 Unix 域套接字需要构建选项 `PAHO_WITH_UNIX_SOCKETS=TRUE`。这仅在类似 *nix 的系统(如 Linux 和 macOS)上可用。在 Windows 上不可用。
## 运行时追踪
许多环境变量控制着 C 库的运行时追踪。
使用 `MQTT_C_CLIENT_TRACE` 开启追踪(值为 ON 时追踪输出到标准输出,任何其他值应指定追踪输出的文件)。
输出的详细程度由 `MQTT_C_CLIENT_TRACE_LEVEL` 环境变量控制 - 有效值为 ERROR、PROTOCOL、MINIMUM、MEDIUM 和 MAXIMUM(从最不详细到最详细)。
变量 `MQTT_C_CLIENT_TRACE_MAX_LINES` 限制了输出的追踪行数。
```
export MQTT_C_CLIENT_TRACE=ON
export MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL
```
## 报告 Bug
请在 Github 项目中创建 issue:https://github.com/eclipse-paho/paho.mqtt.c/issues。
## 更多信息
关于 Paho 客户端的讨论在 [Eclipse paho-dev 邮件列表](https://dev.eclipse.org/mailman/listinfo/paho-dev)中进行。
## 在 Twitter 上关注 Eclipse Paho:[@eclipsepaho](https://twitter.com/eclipsepaho)
有关 MQTT 协议的一般性问题在 [MQTT Google Group](https://groups.google.com/forum/?hl=en-US&fromgroups#!forum/mqtt)中讨论。
通过 [MQTT 社区网站](http://mqtt.org)可以获得更多信息。
## 使用 CMake 构建
目前构建过程支持多种 Linux “风格”,包括 ARM 和 s390、OS X、AIX 和 Solaris,以及 Windows 操作系统。构建过程需要以下工具:
* [CMake](http://cmake.org)
* [GNU Make](https://www.gnu.org/software/make/) 或 [Ninja](https://martine.github.io/ninja/)
* 符合标准的 C 编译器,例如 [gcc](https://gcc.gnu.org/)、[Clang](https://clang.llvm.org/) 等
在基于 Debian 的系统上,这意味着必须安装以下软件包:
```
$ apt-get install build-essential gcc make cmake cmake-gui cmake-curses-gui
```
此外,为了从源代码构建 debian 包,必须安装以下软件包
```
$ apt-get install fakeroot devscripts dh-make lsb-release
```
Ninja 可以从其 github 项目页面的 "releases" 部分下载。或者,也可以构建支持 SSL/TLS 的二进制文件。这需要 OpenSSL 库及其头文件可用。例如,在 Debian 上:
```
$ apt-get install libssl-dev
```
构建文档需要 doxygen 以及可选的 graphviz:
```
$ apt-get install doxygen graphviz
```
### 使用 CMake 构建您的应用程序
如果 Paho C 库是使用 CMake 构建的,并且已经安装在系统上,那么为您的应用程序设置 CMake 构建就相对容易了。(如果尚未构建和安装,请阅读下一节)。
该库可以使用多个选项进行构建,这些选项创建了用于异步或同步使用的库变体;是否支持加密 (SSL/TLS);以及库是共享的还是静态的。CMake 将构建的所有库导出为目标,用户可以选择最适合其应用程序的目标。
该软件包被命名为:**eclipse-paho-mqtt-c**
所有目标的命名空间也是:**eclipse-paho-mqtt-c**
目标名称与库名称相同。即使在共享库和静态库使用相同基本名称的平台上,静态库也会在目标名称后附加 *-static*。因此:
目标|描述
------|-----------
paho-mqtt3a | 异步,无加密
paho-mqtt3as | 异步,支持 SSL/TLS
paho-mqtt3c | 同步,无加密
paho-mqtt3cs | 同步,支持 SSL/TLS
paho-mqtt3a-static | 异步,无加密,静态链接
paho-mqtt3as-static | 异步,支持 SSL/TLS,静态链接
paho-mqtt3c-static | 同步,无加密,静态链接
paho-mqtt3cs-static | 同步,支持 SSL/TLS,静态链接
但请记住,并非所有这些目标都可用。这取决于库是如何构建的。
使用支持加密的异步库 *(paho-mqtt3as)* 的应用程序的示例 *CMakeLists.txt* 可能如下所示:
```
cmake_minimum_required(VERSION 3.5)
project(MyMQTTApp VERSION 1.0.0 LANGUAGES C)
find_package(eclipse-paho-mqtt-c REQUIRED)
add_executable(MyMQTTApp MyMQTTApp.c)
target_link_libraries(MQTTVersion eclipse-paho-mqtt-c::paho-mqtt3as)
```
如果库被安装到了非传统位置,您可能需要使用 `CMAKE_PREFIX_PATH` 告诉 CMake 在哪里找到它。例如,如果您将其安装在 */opt/mqtt/paho.mqtt.c*
```
$ cmake -DCMAKE_PREFIX_PATH=/opt/mqtt/paho.mqtt.c ..
```
### 使用 CMake 构建 Paho C 库
在编译之前,请确定一些变量的值,以便配置功能、库位置和其他选项:
变量 | 默认值 | 描述
------------ | ------------- | -------------
PAHO_BUILD_SHARED | TRUE | 构建共享版本的库
PAHO_BUILD_STATIC | FALSE | 构建静态版本的库
PAHO_HIGH_PERFORMANCE | FALSE | 设置为 true 时,不包含内部追踪和堆跟踪等调试辅助功能。
PAHO_WITH_SSL | FALSE | 定义是否同时构建启用 ssl 的二进制文件的标志。
OPENSSL_ROOT_DIR | ""(系统默认)| 包含您的 OpenSSL 安装的目录(即头文件在 `/usr/local/include` 且库在 `/usr/local/lib` 时为 `/usr/local`)
PAHO_WITH_LIBRESSL | FALSE | 定义是否使用 LibreSSL 而不是 OpenSSL 构建启用 ssl 的二进制文件的标志。
LIBRESSL_ROOT_DIR | ""(系统默认)| 包含您的 LibreSSL 安装的目录(即头文件在 `/usr/local/include` 且库在 `/usr/local/lib` 时为 `/usr/local`)
PAHO_WITH_UNIX_SOCKETS | FALSE | (仅限 *nix 系统)启用对 UNIX 域套接字支持的标志
PAHO_BUILD_DOCUMENTATION | FALSE | 创建并安装基于 HTML 的 API 文档(需要 Doxygen)
PAHO_BUILD_SAMPLES | FALSE | 构建示例程序
PAHO_ENABLE_TESTING | TRUE | 构建测试并运行
MQTT_TEST_BROKER | tcp://localhost:1883 | 用于测试执行期间的 MQTT 代理连接 URL
MQTT_TEST_PROXY | tcp://localhost:1883 | 要使用的测试代理的主机名
MQTT_SSL_HOSTNAME | localhost | 要使用的测试 SSL MQTT 代理的主机名
PAHO_BUILD_DEB_PACKAGE | FALSE | 构建 debian 包
使用这些变量,CMake 可用于生成您的 Ninja 或 Make 文件。使用 CMake 时,默认情况下是源外构建。因此,建议在您选择的构建目录内但在源代码树之外调用所有构建命令。
一个针对构建平台的示例构建会话可能如下所示:
```
$ mkdir /tmp/build.paho ; cd /tmp/build.paho
$ cmake -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_DOCUMENTATION=TRUE \
-DPAHO_BUILD_SAMPLES=TRUE ~/paho.mqtt.c
```
调用 cmake 并指定构建选项也可以使用 cmake-gui 或 ccmake 来执行(参见 https://cmake.org/runningcmake/)。例如:
```
$ ccmake ~/paho.mqtt.c
```
要编译/链接二进制文件、进行安装或生成软件包,请使用以下命令:
```
$ cmake --build .
$ cmake --build . --target install
$ cmake --build . --target package
```
要构建、安装或生成软件包,您也可以在调用初始 CMake 配置步骤(例如 `ninja package` 或 `make -j package`)之后,直接使用生成的构建器,如 _ninja_ 或 _make_。
### 调试构建
通过将 `CMAKE_BUILD_TYPE` 选项的值定义为 `Debug` 可以执行调试构建。例如:
```
$ cmake -DCMAKE_BUILD_TYPE=Debug ~/paho.mqtt.c
```
### 运行测试
测试代码位于 `test` 目录中。可以使用 CMake 构建系统构建和执行测试。测试执行需要运行 MQTT 代理。默认情况下,构建系统使用 `localhost`,但也可以将构建配置为使用外部代理。这些参数在上面的构建要求部分中有文档说明。
在确保 MQTT 代理可用后,可以通过启动代理并如下所述运行 `ctest` 来执行测试:
```
$ python ../test/mqttsas.py &
$ ctest -VV
```
### 交叉编译
使用 CMake 进行交叉编译是通过使用所谓的“工具链文件”来执行的(参见:https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html)。
可以使用 CMake 的 `-DCMAKE_TOOLCHAIN_FILE` 选项指定工具链文件的路径。如果未指定工具链文件,则针对本机构建平台执行构建。
为了您的方便,可以在 Eclipse Paho 的 `cmake` 目录中找到以下平台的工具链文件:
* Linux x86
* Linux ARM11(即 Raspberry Pi)
* Windows x86_64
* Windows x86
提供的工具链文件假定所需的编译器/链接器可以在环境中找到,即您的用户或系统的 PATH 变量中。如果您愿意,也可以在工具链文件中指定编译器的绝对位置。
针对 Raspberry Pi 的示例调用:
```
$ cmake -GNinja -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_SAMPLES=TRUE \
-DPAHO_BUILD_DOCUMENTATION=TRUE \
-DOPENSSL_LIB_SEARCH_PATH=/tmp/libssl-dev/usr/lib/arm-linux-gnueabihf \
-DOPENSSL_INC_SEARCH_PATH="/tmp/libssl-dev/usr/include/openssl;/tmp/libssl-dev/usr/include/arm-linux-gnueabihf" \
-DCMAKE_TOOLCHAIN_FILE=~/paho.mqtt.c/cmake/toolchain.linux-arm11.cmake \
~/paho.mqtt.c
```
适用于 Raspberry Pi 和其他 ARM 目标的编译器可以从 ARM 获取
此示例假定 OpenSSL 库和头文件已安装在 `/tmp/libssl-dev` 目录中。
针对 Windows 64 位的示例调用:
```
$ cmake -DPAHO_BUILD_SAMPLES=TRUE \
-DCMAKE_TOOLCHAIN_FILE=~/paho.mqtt.c/cmake/toolchain.win64.cmake \
~/paho.mqtt.c
```
在这种情况下,库和可执行文件没有链接到 OpenSSL 库。适用于 Windows 平台的交叉编译器可以像这样在类似 Debian 的系统上安装:
```
$ apt-get install gcc-mingw-w64-x86-64 gcc-mingw-w64-i686
```
## GNU Make 构建说明
确保已安装 OpenSSL 开发包。然后从客户端库的基本目录运行:
```
$ make
$ sudo make install
```
这将构建并安装这些库。要卸载:
```
$ sudo make uninstall
```
构建文档需要 doxygen 以及可选的 graphviz。
```
$ make html
```
提供的 GNU Makefile 旨在在 Eclipse Paho 源代码树的 ```build``` 目录中执行所有构建步骤。完成后,可以在 ```build/output``` 目录中找到生成的二进制文件、库和文档。
传递给编译器/链接器的选项可以通过典型的 Unix 构建变量指定:
变量 | 描述
------------ | -------------
CC | C 编译器的路径
CFLAGS | 传递给编译器调用的标志
LDFLAGS | 传递给链接器调用的标志
## 构建aho-mqtt - 使用 vcpkg
您可以使用 [vcpkg](https://github.com/Microsoft/vcpkg) 依赖管理器下载并安装 paho-mqtt:
```
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install paho-mqtt
```
vcpkg 中的 paho-mqtt 端口由 Microsoft 团队成员和社区贡献者保持最新。如果版本已过时,请在 vcpkg 仓库上[创建 issue 或 pull request](https://github.com/Microsoft/vcpkg)。
## 使用 musl libc 的完全静态构建
(作者:Frank Pagliughi)
[musl libc](https://musl.libc.org/) 是构建在 Linux 系统调用 API 之上的 C 标准库的一个实现,包括基本语言标准、POSIX 中定义的接口以及广泛认同的扩展。
封装了这个库的 Rust 库用户一直在抱怨他们无法使用 musl 构建工具进行编译。Musl 是一个小型的标准 C 库,可以进行静态链接。借助最新的 Paho C 库(以及对构建的极小调整),我们现在能够使用 musl 和 Paho C 构建 Rust 应用程序,这些应用程序是完全静态的;对平台没有运行时依赖;甚至不依赖于标准 C 库。
$ ./async_publish
在 'test' 主题上发布消息
$ ldd async_publish
不是动态可执行文件
因此,例如,如果需要为一些较新和较旧的嵌入式 Linux 板维护一套应用程序,则可以部署相同的可执行文件,而无需担心特定板上的 C ABI。
使用 Paho 库的 C 应用程序当然也可以做到这一点。
## Microsoft Windows
### 调用约定
与 Windows 上的 C 程序一样,调用约定是 __cdecl。请参阅此处的 Microsoft 文档:
https://docs.microsoft.com/en-us/cpp/cpp/cdecl?view=vs-2019
如果您从另一种语言调用此库,则可能需要考虑到这一点。
标签:Bash脚本, Eclipse Paho, IoT, MQTT 5.0, SSL/TLS, 中间件, 加密通信, 安全测试工具, 客户端加密, 客户端库, 嵌入式开发, 开源库, 异步编程, 搜索引擎爬虫, 消息发布/订阅, 消息队列, 物联网, 网络编程, 通信协议, 遥测传输