18个版本
0.12.5 | 2024年5月25日 |
---|---|
0.12.3 | 2023年10月25日 |
0.12.1 | 2023年3月20日 |
0.11.1 | 2022年5月3日 |
0.4.0 | 2018年11月21日 |
#19 in 异步
36,536 每月下载量
用于 27 个crate (22 个直接使用)
12MB
304K SLoC
Eclipse Paho MQTT Rust客户端库
适用于Linux/Posix、Mac和Windows等内存管理操作系统的Eclipse Paho MQTT Rust客户端库。
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进行异步操作。
- 传统的异步(token/wait)API
- 同步/阻塞API
需要Paho C v1.3.13或更高版本。
最新动态
要了解此项目的最新公告,请关注
Twitter: @eclipsepaho 和 @fmpagliughi
EMail: Eclipse Paho Mailing List
v0.12.3版本的新功能
- -sys crate现在包装了Paho C v1.3.13,修复了包括重连回调崩溃在内的一些问题。
- 使C日志不那么冗长
- #203
AsyncClient::server_uri()
getter。 - #202 修复断开超时(从秒到毫秒)
v0.12.2版本的新功能
- #209 从Paho C库添加了跟踪/日志语句到Rust日志
- 对订阅者示例进行小幅度清理。
使用 Crate
要使用该库,只需将其添加到您应用程序的 Cargo.toml
依赖项列表中
paho-mqtt = "0.12"
默认情况下,它启用了“捆绑”和“ssl”功能,这意味着它将尝试为目标编译 Paho C 库,使用预构建的绑定,并使用系统 OpenSSL 库启用安全套接字功能。
请注意,此默认行为需要目标 C 编译器和已安装的 CMake。在基于 Ubuntu/Debian 的系统上,您可能需要以下内容
$ sudo apt install libssl-dev build-essential cmake
另外,请注意,构建将默认使用预生成的绑定以加快编译时间。 如果您遇到段错误或其他严重崩溃,首先尝试在您的 crate 中使用“build_bindgen”功能来重新生成目标的绑定。 如果这不能解决问题,请向 GitHub 提交问题。
构建功能
可以通过启用或禁用功能来更改默认行为
- "default" -
[bundled, ssl]
- "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-like 系统上的
pkg-config
、macOS 上的Homebrew
和 Windows 上的vcpkg
。不建议在交叉编译时这样做。 -
如果所有其他方法都失败了,您可能需要使用环境变量设置库的特定位置。例如,在 Windows 上,可能需要进行以下操作
set OPENSSL_DIR=C:\OpenSSL-Win64
因此,默认情况下,您的应用程序将构建 SSL/TLS,前提是已经安装了 OpenSSL 库。在您的 Cargo.toml 中,只需
# Use the system OpenSSL library
paho-mqtt = "0.12"
如果您为目标没有安装 OpenSSL 并想与您的应用程序一起构建它
# Build OpenSSL with the project
paho-mqtt = { version = "0.12", features=["vendored-ssl"] }
如果您想在不使用SSL/TLS的情况下构建您的应用程序,请禁用默认功能,然后(如果需要)再次添加“捆绑”功能。
# Don't use SSL at all
paho-mqtt = { version = "0.12", default-features=false, features=["bundled"] }
Windows
在Windows上,要使用SSL/TLS/WSS安全连接,您必须安装OpenSSL的一个副本或使用vendored-ssl功能与应用程序一起构建它。安装库需要更多的时间,但会导致构建时间显著加快。
如果您安装了OpenSSL,通常需要告诉Rust构建工具在哪里可以找到它。最简单的方法是设置环境变量OPENSSL_DIR
,如下所示:
set OPENSSL_DIR=C:\OpenSSL-Win64
将其指向您安装库的位置。或者,您可以告诉Cargo使用vendored-ssl功能与应用程序一起构建它。
# Build OpenSSL with the project
paho-mqtt = { version = "0.12", features=["vendored-ssl"] }
使用MUSL进行完全静态构建
使用musl可以使您创建完全不依赖于任何共享库的完全静态应用程序。您需要为Rust编译器提供musl目标,以及为您的目标提供musl构建工具。
然后您可以使用Cargo构建您的应用程序,如下所示:
$ cargo build --target=x86_64-unknown-linux-musl
当使用musl与SSL/TLS一起使用时,您需要一个为musl构建的OpenSSL库的静态版本。如果您没有构建和安装它,您可以使用vendored-ssl。因此,在您的Cargo.toml中:
paho-mqtt = { version = "0.12", features=["vendored-ssl"] }
当使用musl与OpenSSL一起使用时,似乎您还需要手动链接C库。有两种方法可以做到这一点。首先,您可以为您的应用程序创建一个简单的build.rs
,指定链接:
fn is_musl() -> bool {
std::env::var("CARGO_CFG_TARGET_ENV").unwrap() == "musl"
}
fn main() {
if is_musl() {
// Required for OpenSSL with musl
println!("cargo:rustc-link-arg=-lc");
}
}
第二种选择是告诉Cargo在为musl目标编译时始终链接C库。将以下行添加到$HOME/.cargo/config
文件中
[target.x86_64-unknown-linux-musl]
rustflags = ["-C", "link-arg=-lc"]
支持的最小Rust版本(MSRV)
v1.63.0
此包使用Rust Edition 2021,需要MSRV为1.63.0。尽管它可能可以与稍微旧一点的编译器版本构建和运行,但这是最早由开发人员测试和维护的版本。
开发这个包
该库是一个标准的Rust "crate",使用Cargo构建工具。它使用标准的cargo命令进行构建
$ cargo build
构建库,并构建-sys子crate和捆绑的Paho C库。它包含SSL,因为它被定义为默认功能。
$ cargo build --examples
构建examples子目录中的库和示例应用程序。
$ cargo test
构建和运行单元测试。
$ cargo doc
生成参考文档。
Paho C库和
Paho Rust包
Paho Rust包是Paho C库的包装器。这个版本是专门匹配Paho C v 1.3.x的,目前正在使用版本1.3.13。它通常不会与C库的新版本构建,因为C库通过扩展结构来扩展功能,从而破坏Rust构建。
项目包括一个名为paho-mqtt-sys的Rust -sys包,它提供对C库的不安全绑定。仓库包含一个指向Rust包需要的特定版本的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。该 openssl-sys
crate 支持自动检测 OpenSSL 安装,使用环境变量手动指向 OpenSSL 安装,或者构建并静态链接到 OpenSSL 的捆绑副本(有关所有可用选项,请参阅 openssl-sys
文档中的 选项)。要使用捆绑选项,请使用 vendored-ssl
功能,该功能还启用了 bundled
和 ssl
功能。
构建带有 SSL 会自动发生,因为 ssl
是默认功能。它需要为目标安装 OpenSSL 库。如果它们不在标准位置,则应设置 OPENSSL_DIR
环境变量,指向顶层安装路径,其中 .lib、.a 和其他库文件位于根目录下的 lib/
目录中。使用如下
$ export OPENSSL_DIR=/home/myacct/openssl
或库安装的任何位置。
可以通过使用 --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 构建的开发树时是必要的。现在由于在所有地方都使用 CMake,这似乎不再那么必要了。
链接到已安装的 Paho C 库
如果预期目标系统上已安装正确的 Paho C 库版本,则最简单的解决方案是使用预生成的绑定并指定对共享 Paho C 库的链接。
$ cargo build --no-default-features --features "ssl"
这在生产环境中特别有用,因为在这些环境中系统受到良好控制,例如使用像yocto或buildroot这样的全系统构建工具时。分别构建或交叉编译包可能更容易。
再次强调,如果不需要,可以省略ssl
功能。
在构建一个将与目标系统独立发布的应用程序时,应谨慎使用此选项,因为它假设C库的非常特定版本,如果目标上没有这个版本,则将失败。
Rust-C 绑定
如上所述,该包可以选择使用bindgen创建与Paho C库的绑定。
https://rust-lang-nursery.github.io/rust-bindgen/
每次构建Rust包时都生成绑定会消耗很多时间和资源。在本地构建小型目标(如ARM板)时尤为明显。
但是,每个Rust包的版本都是针对Paho C库的特定版本构建的,这意味着对于特定的目标,绑定在构建之间永远不会改变。因此,我们可以为特定目标创建一次绑定,然后在此之后快速构建。
该包包含为: paho-mqtt-sys/bindings
中的几个常用目标提供预构建绑定。这些文件具有以下形式的名称
bindings_paho_mqtt_c_<version>-<target>.rs
其中一些包括
bindings_paho_mqtt_c_1.3.13-x86_64-unknown-linux-gnu.rs
bindings_paho_mqtt_c_1.3.13-x86_64-pc-windows-msvc.rs
bindings_paho_mqtt_c_1.3.13-aarch64-unknown-linux-gnu.rs
bindings_paho_mqtt_c_1.3.13-armv7-unknown-linux-gnueabihf.rs
bindings_paho_mqtt_c_1.3.13-x86_64-apple-darwin.rs
bindings_paho_mqtt_c_1.3.13-default-32.rs
bindings_paho_mqtt_c_1.3.13-default-64.rs
可以使用命令行bindgen工具为Paho C库的新版本或不同的目标平台创建绑定。例如,在x86版本的Windows上使用MSVC,您可以像这样重新生成绑定
$ cd paho-mqtt-sys
$ bindgen wrapper.h -o bindings/bindings_paho_mqtt_c_1.3.13-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.13-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
进行完整构建,这包括Raspberry Pi、BeagleBones、UDOO Neo和其他许多ARM制造商的板子
$ cargo build --target=armv7-unknown-linux-gnueabihf --examples
这构建了主要包、-sys包,并交叉编译了Paho C库。它使用SSL,因此需要您在交叉编译器中安装SSL开发库的版本。如果SSL库不可用,您可以在Rust构建过程中编译和链接它们,使用--vendored-ssl
功能
$ 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库和工具创建完全静态的应用程序构建应该相对简单。
在最近的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
特质。可以在以下位置找到它: