The Eclipse Paho MQTT Rust client library on memory-managed operating systems such as Linux/Posix, Mac, and Windows.
The Rust crate is a safe wrapper around the Paho C Library.
The initial version of this crate is a wrapper for the Paho C library, and includes all of the features available in that library, including:
Requires Paho C v1.3.16, or possibly later.
To keep up with the latest announcements for this project, follow:
Mastodon: @fpagliughi@fosstodon.org
EMail: Eclipse Paho Mailing List
Version v0.14.0 now wraps Paho C v0.3.16, which was mainly concerned with internal performance improvements. For may aplications, there is a noticable decrease in latency for a number of operations.
Some additional updates:
For the complete list of updates and bug fixes, see the CHANGELOG
This library works with Rust async/await features, but is agnostic to async runtimes. It should work with any runtime for the supported operating systems (Linux, Windows, and MacOS), and is tested against tokio and smol. It was also working against async-std but since that project is no longer maintained, we no longer test with it. The library does not use a runtime for internal operations.
This library pre-dates Rust async/await by a number of years. It was originally written with a legacy async API in which I/O operations were started by the calling function, but those functions did not block awaiting the operation to complete. Instead, the I/O functions returned a Token object which could be used to monitor progress of the operation, or later block the caller to wait for it to complete. Internally the Token uses a condition variable to signal when the operation completes and fill in the result. The I/O operation and signaling are performed by a pair of threads internal to the library which run the operations and signal the condition variable.
To make the library compatible with the async/await paradigm, the Token simply implemented the std::future::Future trait. This made them compatible with modern Rust, but have a few implications:
Future that are compatible with any runtime that can poll it.Token::wait() functions which block the calling thread waiting for completion.To use the library, simply add this to your application's Cargo.toml dependencies list:
paho-mqtt = "0.14"
By default it enables the features "bundled" and "ssl" meaning it will attempt to compile the Paho C library for the target, using the pre-built bindings, and will enable secure sockets capabilities using the system OpenSSL library.
Note that this default behavior requires a C compiler for the target and CMake to be installed. On an Ubuntu/Debian-based system you might need something like:
$ sudo apt install libssl-dev build-essential cmake
Also note that the build will use pre-generated bindings by default to speed up compile times. If you experience segfaults or other hard crashes, the first thing to do is try using the "build_bindgen" feature in your crate to regenerate the bindings for your target. If that doesn't fix it, then please submit an issue on GitHub.
The default behaviour can be altered by enabling or disabling the features:
[bundled, ssl]The bundled feature requires CMake and a C compiler for the target.
The vendored-ssl feature requires the target C compiler as well, but also requires Perl and make.
The default build attempts to speed up the build by using pre-generated C bindings for the recommended Paho C library. There are a number of bindings for common build targets, and when the specific target is not found, it resorts to a default for the target word size (32-bit or 64-bit).
If your using a non-standard target and/or get a SEGFAULT, the first thing to try is using the build_bindgen feature. That will generate a new binding file during the build for the specific target, which should fix the segfault in most cases.
Starting with Version 0.9.0 we are using the openssl-sys crate which allows for further modification of the behavior through environment variables, such as specifying the location of the OpenSSL library or linking it statically.
For more information read the Rust OpenSSL Docs, carefully.
In particular:
If you use vendored-ssl, you need a C compiler for the target, Perl, and make.
If you don't use vendored-ssl, it will attempt to use a package manager on the build host to find the library: pkg-config on Unix-like systems, Homebrew on macOS, and vcpkg on Windows. This is not recommended when cross-compiling.
If all else fails, you may need to set the specific location of the library with an environment variable. For example, on Windows, perhaps do something like this:
set OPENSSL_DIR=C:\OpenSSL-Win64
So, by default, your application will build for SSL/TLS, assuming an existing install of the OpenSSL library. In your Cargo.toml, just:
# Use the system OpenSSL library
paho-mqtt = "0.14"
If you don't have OpenSSL installed for your target and want to build it with your app:
# Build OpenSSL with the project
paho-mqtt = { version = "0.14", features=["vendored-ssl"] }
If you want to build your app without SSL/TLS, disable the default features, then add "bundled" back in (if desired):
# Don't use SSL at all
paho-mqtt = { version = "0.14", default-features=false, features=["bundled"] }
On Windows, to use SSL/TLS/WSS secure connections, you must either install a copy of OpenSSL or build it with the application using the vendored-ssl feature. Installing the library takes more time up front, but results in significantly faster build times.
If you install OpenSSL, you usually need tell the Rust build tools where to find it. The easiest way is setting the OPENSSL_DIR environment variable, like:
set OPENSSL_DIR=C:\OpenSSL-Win64
Point it to wherever you installed the library. Alternately, you can tell Cargo to build it with the app, using the vendored-ssl feature:
# Build OpenSSL with the project
paho-mqtt = { version = "0.14", features=["vendored-ssl"] }
To be able to build the library on macOS as Universal Binary, which is working for both architectures Apple Silicon and Intel x86_64 alike, you need to run at least Rust 1.66 as it requires this PR from Rust compiler team: https://github.com/rust-lang/rust/pull/98736.
To set up your build system please update your Rust compiler toolchain and add both macOS targets as follows:
$ rustup update stable
$ rustup +stable add target x86_64-apple-darwin
$ rustup +stable add target aarch64-apple-darwin
You can build the library for both architectures now by running:
$ cargo build --target x86_64-apple-darwin
$ cargo build --target aarch64-apple-darwin
To combine the two separate libraries into one universal binary please use the lipo command-line tool provided with the Xcode command-line programs:
$ lipo -create -arch arm64 <path-to-aarch64-apple-darwin-binary> -arch x86_64 <path-to-x86_64-apple-darwin-binary> -o <path-to-universal-binary>
Using musl would allow you to create fully-static applications that do not rely on any shared libraries... at all. You would need a musl target for your Rust compiler, and the musl build tools for your target ar well.
Then you would be able to use Cargo to build your application, like:
$ cargo build --target=x86_64-unknown-linux-musl
On a recent Ubuntu/Mint Linux host it should work as follows, but should be similar on any development host once the tools are installed.
First install the Rust compiler for musl and the tools:
$ rustup target add x86_64-unknown-linux-musl
$ sudo apt install musl-tools
Check the musl compiler:
$ musl-gcc --version
cc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
...
Building without SSL is like this:
$ cargo build --no-default-features --features="bundled" \
--target=x86_64-unknown-linux-musl --examples
When using SSL/TLS with musl, you need a static version of the OpenSSL library built for musl. If you don't have one built and installed, you can use vendored-ssl. So, in your Cargo.toml:
paho-mqtt = { version = "0.14", features=["vendored-ssl"] }
When using musl with OpenSSL, it appears that you also need to manually link with the C library. There are two ways to do this. First, you can create a simple build.rs for your application, specifying the link:
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");
}
}
The second option is to tell Cargo to always link the C library when compiling for the musl target. Add the following lines to the $HOME/.cargo/config file:
[target.x86_64-unknown-linux-musl]
rustflags = ["-C", "link-arg=-lc"]
v1.73.0
This package uses Rust Edition 2021, and requires an MSRV of 1.73.0. Although it may build and work with slightly older versions of the compiler, this is the oldest version being tested and maintained by the developers.
The library is a standard Rust "crate" using the Cargo build tool. It uses the standard cargo commands for building:
$ cargo build
Builds the library, and also builds the -sys subcrate and the bundled Paho C library. It includes SSL, as it is defined as a default feature.
$ cargo build --examples
Builds the library and sample applications in the examples subdirectory.
$ cargo test
Builds and runs the unit tests.
$ cargo doc
Generates reference documentation.
The Paho Rust crate is a wrapper around the Paho C library. This version is specifically matched to Paho C v 1.3.x, and is currently using version 1.3.16. It will generally not build against newer versions of the C library, as the C lib expands functionality by extending structures, thus breaking the Rust build.
The project includes a Rust -sys crate, called paho-mqtt-sys, which provides unsafe bindings to the C library. The repository contains a Git submodule pointing to the specific version of the C library that the Rust crate requires, and by default, it will automatically build and link to that library, using pre-generated C bindings that are also included in the repo.
When building, the user has several options:
$ claude mcp add paho.mqtt.rust \
-- python -m otcore.mcp_server <graph>