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

paho-mqtt

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

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 异步

Download history 7329/week @ 2024-05-02 9563/week @ 2024-05-09 8795/week @ 2024-05-16 6895/week @ 2024-05-23 9116/week @ 2024-05-30 9415/week @ 2024-06-06 7730/week @ 2024-06-13 8135/week @ 2024-06-20 6654/week @ 2024-06-27 6552/week @ 2024-07-04 7629/week @ 2024-07-11 8412/week @ 2024-07-18 7576/week @ 2024-07-25 8582/week @ 2024-08-01 8667/week @ 2024-08-08 10033/week @ 2024-08-15

36,536 每月下载量
用于 27 个crate (22 个直接使用)

EPL-2.0 许可证

12MB
304K SLoC

Rust 252K 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

适用于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 编译器,但还需要 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-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 功能,该功能还启用了 bundledssl 功能。

构建带有 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 功能还启用了 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 构建的开发树时是必要的。现在由于在所有地方都使用 CMake,这似乎不再那么必要了。

链接到已安装的 Paho C 库

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

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

这在生产环境中特别有用,因为在这些环境中系统受到良好控制,例如使用像yoctobuildroot这样的全系统构建工具时。分别构建或交叉编译包可能更容易。

再次强调,如果不需要,可以省略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

Rust书籍

例如,为了对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_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

依赖关系