1 个不稳定版本
0.11.1 | 2024 年 5 月 13 日 |
---|
#1420 在 网络编程
12MB
304K SLoC
Eclipse Paho MQTT Rust 客户端库
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 新特性
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 编译器,但还需要 Perl
和 make
。
默认构建尝试通过使用为推荐的 Paho C 库预生成的 C 绑定来加快构建速度。存在针对常见构建目标的大量绑定,当找不到特定目标时,它将回退到针对目标字长(32 位或 64 位)的默认值。
如果您使用的是非标准目标并/或遇到 SEGFAULT,首先尝试使用 build_bindgen 功能。这将生成一个针对特定目标的新的绑定文件,这应该在大多数情况下修复段错误。
使用 SSL/TLS
从 0.9.0 版本开始,我们使用 openssl-sys crate,它允许通过环境变量进一步修改行为,例如指定 OpenSSL 库的位置或将其静态链接。
有关更多信息,请参阅 Rust OpenSSL 文档,请仔细阅读。
特别是
-
如果您使用 vendored-ssl,则需要为目标安装 C 编译器、
Perl
和make
。 -
如果您不使用 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
功能,它还启用了bundled
和ssl
功能。
带有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
功能还启用了 bundled
和 ssl
功能,因此以下任一命令都将有效
$ 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"
这在生产环境中特别有用,其中系统得到很好的控制,例如在使用如 yocto 或 buildroot 等完整系统构建工具时。单独构建或交叉编译包可能更容易。
同样,如果不需要,可以省略 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
例如,为了对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_TRACE
和MQTT_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
特质。它可以在以下位置找到: