#mqtt-client #mqtt #paho #messaging #iot

paho-mqtt-zaack

官方 Eclipse Paho MQTT Rust 客户端库。这是一个 Paho C 库的包装器

1 个不稳定版本

0.11.1 2024 年 5 月 13 日

#1420网络编程

EPL-1.0 许可证

12MB
304K SLoC

Rust 251K SLoC // 0.0% comments C 43K SLoC // 0.1% comments JavaScript 6K SLoC // 0.1% comments Python 3K SLoC // 0.1% comments Shell 151 SLoC // 0.3% comments Bitbake 60 SLoC // 0.3% comments RPM Specfile 57 SLoC Batch 10 SLoC // 0.2% comments

Eclipse Paho MQTT Rust 客户端库

docs.rs crates.io GitHub contributors

Eclipse Paho MQTT Rust 客户端库适用于 Linux/Posix、Mac 和 Windows 等内存管理操作系统。

Rust crate 是 Paho C 库的安全包装。

特性

此 crate 的初始版本是 Paho C 库的包装器,包括该库中所有可用的功能,包括

  • 支持 MQTT v5、3.1.1 和 3.1
  • 网络传输
    • 标准 TCP 支持
    • SSL / TLS(可选 ALPN 协议)
    • WebSocket(安全和不安全),以及可选代理
  • QoS 0、1 和 2
  • 遗愿和遗嘱(LWT)
  • 消息持久化
    • 文件或内存持久化
    • 用户定义的键/值持久化(包括 Redis 示例)
  • 自动重连
  • 离线缓冲
  • 高可用性
  • 多个 API
    • 使用 Rust Futures 和 Streams 进行异步操作。
    • 传统的异步(令牌/等待)API
    • 同步/阻塞 API

需要 Paho C v1.3.10,或更高版本。

最新消息

要了解此项目的最新公告,请关注

Twitter: @eclipsepaho@fmpagliughi

电子邮件: Eclipse Paho 邮件列表

Mattermost: Eclipse Mattermost Paho 频道

v0.11.1 新特性

  • #156 改进了 TopicMatcher
    • 不需要项目类型实现 Default 特性
    • 匹配迭代器返回键/值元组(而不仅仅是值)。
  • #154 添加了用于检索 client_id 的公共接口。

v0.11.0 新特性

  • 更新为支持 Paho C v1.3.10
  • 添加了新的客户端函数,用于停止消费/流式传输和移除回调。
  • 为 -sys crate 开始编写 README。
  • 修复了大量 lint。Clippy 报告是干净的。
  • #152 当接收器断开时,消费者不会崩溃。
  • #113 现在构建现在尊重 OPENSSL_STATIC 标志(如果设置了 OPENSSL_DIR 或其他路径标志)。
  • #145 impl From<Error> for io::Error MQTT 错误可以轻松转换为 I/O 错误。

使用 Crate

要使用此库,只需将以下内容添加到您的应用程序的 Cargo.toml 依赖项列表中

paho-mqtt = "0.11"

默认情况下,它启用了 "bundled" 和 "ssl" 功能,这意味着它将尝试为目标编译 Paho C 库,使用预构建的绑定,并启用安全套接字功能。

请注意,此默认行为需要为目标安装 C 编译器和 CMake

另外,请注意,默认情况下,构建将使用预生成的绑定以加快编译时间。如果您遇到段错误或其他严重崩溃,首先尝试使用您的 crate 中的 "build_bindgen" 功能来重新生成针对您的目标的绑定。 如果这不起作用,请请提交一个关于 GitHub 的问题。

可配置功能

可以通过启用或禁用功能来更改默认行为

  • "bundled" - 是否在包含 paho-mqtt-sys crate 的 Git 子模块中构建 Paho C 库。这类似于其他 Rust 项目中的 "vendored" 功能。
  • "build_bindgen" - 是否使用 bindgen 构建针对目标的绑定。如果没有设置,构建将尝试找到并使用针对目标预构建的绑定。
  • "ssl" - 是否启用使用安全套接字和安全 WebSocket 连接。
  • "vendored-ssl" - 是否构建 OpenSSL。这传递 "vendored" 选项到 openssl-sys crate。

"bundled" 功能需要 CMake 和目标 C 编译器。

"vendored-ssl" 功能也需要目标 C 编译器,但还需要 Perlmake

默认构建尝试通过使用为推荐的 Paho C 库预生成的 C 绑定来加快构建速度。存在针对常见构建目标的大量绑定,当找不到特定目标时,它将回退到针对目标字长(32 位或 64 位)的默认值。

如果您使用的是非标准目标并/或遇到 SEGFAULT,首先尝试使用 build_bindgen 功能。这将生成一个针对特定目标的新的绑定文件,这应该在大多数情况下修复段错误。

使用 SSL/TLS

从 0.9.0 版本开始,我们使用 openssl-sys crate,它允许通过环境变量进一步修改行为,例如指定 OpenSSL 库的位置或将其静态链接。

有关更多信息,请参阅 Rust OpenSSL 文档请仔细阅读

特别是

  • 如果您使用 vendored-ssl,则需要为目标安装 C 编译器、Perlmake

  • 如果您不使用 vendored-ssl,则它将尝试在构建主机上使用包管理器来查找库:Unix 类系统上的 pkg-config、macOS 上的 Homebrew 和 Windows 上的 vcpkg。在交叉编译时不推荐这样做。

  • 如果所有其他方法都失败,您可能需要使用环境变量设置库的特定位置。例如,在 Windows 上,您可能需要执行以下操作

    set OPENSSL_DIR=C:\OpenSSL-Win64

开发 Crate

这个库是一个标准的Rust "crate",使用Cargo构建工具。它使用标准的cargo命令进行构建

$cargo build

构建库,同时构建-sys子crate和捆绑的Paho C库。它包含SSL,因为它被定义为默认功能。

$cargo build --示例

构建库和examples子目录中的示例应用程序。

$cargo test

构建并运行单元测试。

$cargo doc

生成参考文档。

Paho C库和paho-mqtt-sys

Paho Rust crate是Paho C库的包装器。这个版本是专门匹配Paho C v 1.3.x的,目前正在使用版本1.3.10。它通常不会与新版本的C库构建,因为C库通过扩展结构来扩展功能,从而破坏了Rust的构建。

项目包含一个名为paho-mqtt-sys的Rust -sys crate,它提供了对C库的不安全绑定。仓库中包含一个指向Rust crate所需的特定版本C库的Git子模块,默认情况下,它将自动构建和链接到该库,使用库中也包含的预生成的C绑定。

在构建时,用户有几种选择

  • 使用预生成的绑定和SSL构建捆绑的库(默认)。
  • 构建捆绑的库,并编译一个OpenSSL副本进行静态链接。
  • 构建捆绑的库,但在构建时重新生成绑定。
  • 使用外部库,位置由环境变量指定,在构建时生成绑定。
  • 使用预安装的库和预生成的绑定。

这些是通过cargo功能选择的,下面将解释。

构建捆绑的Paho C库

这是默认设置

$ cargo build

这将从Git初始化和更新C库源代码,然后使用cmake crate构建C库的静态版本,并将其链接进来。默认情况下,构建将使用预生成的绑定,位于bindings/bindings_paho_mqtt_X_Y_Z.rs中,其中X_Y_Z是当前支持的库版本。

构建的默认功能是:["bundled", "ssl"]

当构建捆绑的库时,绑定也可以在构建时重新生成。这在构建不常见/未测试的平台时特别有用,以确保该系统的正确绑定。这是通过添加"build_bindgen"功能完成的

$ cargo build --features "build_bindgen"

在这种情况下,它将根据捆绑的C仓库中的头文件生成绑定。

绑定的缓存版本是针对特定目标的。如果预生成的版本不存在于目标中,则需要生成它。

构建带有或没有SSL/TLS的Paho C库

要构建带有SSL/TLS的Paho C库,我们依赖于openssl-sys crate。The openssl-sys crate支持自动检测OpenSSL安装,手动使用环境变量指向OpenSSL安装,或者构建并静态链接到存储库的OpenSSL副本(有关所有可用选项,请参阅openssl-sys文档)。要使用存储库选项,请使用vendored-ssl功能,它还启用了bundledssl功能。

带有SSL的构建是自动发生的,因为ssl是一个默认功能。它要求目标上安装了OpenSSL库。如果它们位于非标准位置,则应设置OPENSSL_DIR环境变量,指向顶级安装路径,其中包含在根目录下lib/目录中的.lib、.a和其他库文件。使用如下所示

$ export OPENSSL_DIR=/home/myacct/openssl

或 wherever the library was installed.

您也可以通过使用 --no-default-features 来构建不带 SSL 的 crate。例如,为了构建不带安全套接字的捆绑式 Paho C 库

$ cargo build --no-default-features --features "bundled"
静态链接 OpenSSL

启用 --vendored-ssl 功能,以使用编译并静态链接的 OpenSSL 版本的 crate 进行构建。该 --vendored-ssl 功能还启用了 bundledssl 功能,因此以下任一命令都将有效

$ cargo build --features "vendored-ssl"
$ cargo build --no-default-features --features "vendored-ssl"

链接外部 Paho C 库

该 crate 可以生成指向本地文件系统不同位置的 Paho C 库副本的绑定,并将其链接到该库。

$ cargo build --no-default-features --features "build_bindgen,ssl"

如果不需要,可以省略 ssl 功能。

C 库的位置通过环境变量指定

PAHO_MQTT_C_DIR= ...path to install directory...

假设头文件位于指定目录下的 include/ 目录中,库位于其 lib/ 目录下。这通常是正常安装的情况。

或者,这可以用每个头文件和库目录的单独环境变量来表示

PAHO_MQTT_C_INCLUDE_DIR= ...path to headers...
PAHO_MQTT_C_LIB_DIR= ...path to library...

在这种情况下,头文件和库可以独立找到。这在构建针对使用 GNU Make 构建的开发树的 Paho C 库时是必要的。现在由于到处都使用 CMake,这似乎不那么必要了。

链接到已安装的 Paho C 库

如果预期目标系统上已安装正确的 Paho C 库版本,最简单的解决方案是使用预生成的绑定并指定链接到共享 Paho C 库。

$ cargo build --no-default-features --features "ssl"

这在生产环境中特别有用,其中系统得到很好的控制,例如在使用如 yoctobuildroot 等完整系统构建工具时。单独构建或交叉编译包可能更容易。

同样,如果不需要,可以省略 ssl 功能。

当构建一个将独立于目标系统发货的应用程序时,应谨慎使用此选项,因为它假设存在一个 非常特定 的 C 库版本,并且如果目标上没有这个版本将会失败。

Rust-C 绑定

如上所述,crate 可以选择使用 bindgen 来创建 Paho C 库的绑定。

https://rust-lang-nursery.github.io/rust-bindgen/

每次构建 Rust crate 时都生成绑定会消耗大量时间和资源。在本地构建像 ARM 板这样的小目标时,这一点尤为明显。

但是,每次 Rust crate 的发布都是针对 Paho C 库的特定版本构建的,这意味着对于特定目标,绑定从构建到构建不会改变。因此,我们可以为目标创建一次绑定,然后在其后的快速构建中使用它们。

crate 随带一些预构建绑定,这些绑定适用于几个流行的目标:paho-mqtt-sys/bindings。这些文件具有以下形式的名称

bindings_paho_mqtt_c_<version>-<target>.rs

其中一些包括

bindings_paho_mqtt_c_1.3.10-x86_64-unknown-linux-gnu.rs
bindings_paho_mqtt_c_1.3.10-x86_64-pc-windows-msvc.rs
bindings_paho_mqtt_c_1.3.10-aarch64-unknown-linux-gnu.rs
bindings_paho_mqtt_c_1.3.10-armv7-unknown-linux-gnueabihf.rs
bindings_paho_mqtt_c_1.3.10-x86_64-apple-darwin.rs
bindings_paho_mqtt_c_1.3.10-default-32.rs
bindings_paho_mqtt_c_1.3.10-default-64.rs

可以使用命令行 bindgen 工具为 Paho C 库的新版本或不同目标平台创建绑定。例如,在 Windows 的 x86 版本上使用 MSVC,可以像这样重新生成绑定

$ cd paho-mqtt-sys
$ bindgen wrapper.h -o bindings/bindings_paho_mqtt_c_1.3.10-x86_64-pc-windows-msvc.rs -- -Ipaho.mqtt.c/src

要为不同的目标创建绑定,使用 TARGET 环境变量。例如,要在 64 位主机上构建 Windows 的 32 位 MSVC 绑定,请使用 i686-pc-windows-msvc 目标

$ TARGET=i686-pc-windows-msvc bindgen wrapper.h -o bindings/bindings_paho_mqtt_c_1.3.10-i686-pc-windows-msvc.rs -- -Ipaho.mqtt.c/src
bindgen 链接器问题

Bindgen需要系统上安装一个相对较新的Clang库版本,建议使用v3.9或更高版本。然而,bindgen的依赖似乎会寻找系统上安装的最旧的Clang版本。在Ubuntu 14.04或16.04上,默认的Clang v3.6可能会引起一些问题,尽管根据当前的Paho构建配置,它应该可以工作。

但最安全的方法是将环境变量LIBCLANG_PATH设置为一个支持的版本,例如

export LIBCLANG_PATH=/usr/lib/llvm-3.9/lib

交叉编译

cmake软件包会自动处理库的交叉编译。您需要在系统上安装一个C交叉编译器。有关交叉编译Rust的一般信息,请参见以下链接

https://github.com/japaric/rust-cross

Rust图书

例如,为了对ARMv7进行完全构建,这包括树莓派、BeagleBones、UDOO Neo和其他许多ARM制造商的板子

$ cargo build --target=armv7-unknown-linux-gnueabihf --examples

这将构建主crate、-sys crate,并交叉编译Paho C库。它使用SSL,因此需要您安装一个与交叉编译器一起安装的SSL开发库版本。如果SSL库不可用,您可以使用--vendored-ssl功能作为Rust构建的一部分进行编译和链接

$ cargo build --target=armv7-unknown-linux-gnueabihf --features="vendored-ssl" --examples

如果您不想使用交叉编译器的SSL

$ cargo build --target=armv7-unknown-linux-gnueabihf --no-default-features --features="bundled" --examples

如果安装的交叉编译器的三元组与Rust目标的三元组不完全匹配,您可能还需要纠正环境变量CC

$ CC_armv7-unknown-linux-gnueabihf=armv7-unknown-linux-gnueabihf-gcc cargo build --target=armv7-unknown-linux-gnueabihf --features="vendored-ssl" --examples

使用"cross"项目进行交叉编译。

cross项目是一个交叉编译构建工具,它利用预先装满构建工具的docker容器来支持多个目标。它需要在您的系统上安装并运行Docker

然后构建/安装cross工具

$ cargo install cross

之后,您应该能够为任何支持的的目标构建项目。只需使用cross命令而不是cargo。

$ cross build --target=armv7-unknown-linux-gnueabihf \
    --features=vendored-ssl --examples

使用musl进行完全静态构建

从v0.9版本开始,应该可以相对容易地使用musl库和工具创建使用Paho crate的应用程序的完全静态构建。

在最近的Ubuntu/Mint Linux主机上,应该如下操作,但一旦安装了工具,任何开发主机都应该类似。

首先安装musl的Rust编译器和工具

$ rustup target add x86_64-unknown-linux-musl
$ sudo apt install musl-tools

检查musl编译器

$ musl-gcc --version
cc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
...

不使用SSL的构建如下

$  cargo build --no-default-features --features="bundled" \
    --target=x86_64-unknown-linux-musl --examples

日志记录

Rust库使用log软件包输出调试和跟踪信息。应用程序可以选择使用可用的日志记录实现之一或定义自己的实现。更多信息请参见

https://docs.rs/log/0.4.0/log/

示例应用程序使用环境日志软件包env_logger,通过RUST_LOG环境变量进行配置。要使用此功能,在示例中使用Rust MQTT API之前指定以下调用

env_logger::init().unwrap();

然后库将输出环境定义的信息。使用方法如下

$ RUST_LOG=debug ./async_publish
DEBUG:paho_mqtt::async_client: Creating client with persistence: 0, 0x0
DEBUG:paho_mqtt::async_client: AsyncClient handle: 0x7f9ae2eab004
DEBUG:paho_mqtt::async_client: Connecting handle: 0x7f9ae2eab004
...

此外,底层的Paho C库有其自己的日志记录能力,可以用于跟踪网络和协议事务。它通过环境变量MQTT_C_CLIENT_TRACEMQTT_C_CLIENT_TRACE_LEVEL进行配置。前者指定日志文件名,特殊值"ON"表示输出到stdout。后者指定以下级别之一:ERROR、PROTOCOL、MINIMUM、MEDIUM和MAXIMUM。

export MQTT_C_CLIENT_TRACE=ON
export MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL

示例

一些小型的示例应用程序可以在examples目录中找到。以下是一个小型MQTT发布者的示例:

use std::process;

extern crate paho_mqtt as mqtt;

fn main() {
    // Create a client & define connect options
    let cli = mqtt::Client::new("tcp://127.0.0.1:1883").unwrap_or_else(|err| {
        println!("Error creating the client: {:?}", err);
        process::exit(1);
    });

    let conn_opts = mqtt::ConnectOptionsBuilder::new()
        .keep_alive_interval(Duration::from_secs(20))
        .clean_session(true)
        .finalize();

    // Connect and wait for it to complete or fail
    if let Err(e) = cli.connect(conn_opts).wait() {
        println!("Unable to connect:\n\t{:?}", e);
        process::exit(1);
    }

    // Create a message and publish it
    let msg = mqtt::Message::new("test", "Hello world!");
    let tok = cli.publish(msg);

    if let Err(e) = tok.wait() {
        println!("Error sending message: {:?}", e);
    }

    // Disconnect from the broker
    let tok = cli.disconnect();
    tok.wait().unwrap();
}

外部库和工具

有多个外部项目正在开发中,这些项目使用或增强了Paho MQTT Rust库。这些可以在使用Rust库的系统中使用,或作为其使用的进一步示例。

Redis持久化

mqtt-redis创建允许使用Redis作为持久化存储。它还提供了一个创建用户定义持久化的好例子,该持久化实现了ClientPersistence特质。它可以在以下位置找到:

https://github.com/fpagliughi/mqtt.rust.redis

依赖项