Paho.mqtt.rust
paho.mqtt.rust
Install / Use
/learn @eclipse-paho/Paho.mqtt.rustREADME
Eclipse Paho MQTT Rust Client Library
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.
Features
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:
- Supports MQTT v5, 3.1.1, and 3.1
- Network Transports:
- Standard TCP support
- UNIX-domain sockets (*nix only)
- SSL / TLS (with optional ALPN protocols)
- WebSockets (secure and insecure), and optional Proxies
- QoS 0, 1, and 2
- Last Will and Testament (LWT)
- Message Persistence
- Built-in file or memory persistence
- User-defined key/value persistence (including example for Redis)
- Automatic Reconnect
- Offline Buffering
- High Availability
- Several API's:
- Async/Await with Rust Futures and Streams for asynchronous operations.
- Agnostic to async runtimes. Tested with tokio and smol.
- Traditional asynchronous (token/wait) API
- Synchronous/blocking API
- Async/Await with Rust Futures and Streams for asynchronous operations.
Requires Paho C v1.3.16, or possibly later.
Latest News
To keep up with the latest announcements for this project, follow:
Mastodon: @fpagliughi@fosstodon.org
EMail: Eclipse Paho Mailing List
What's New in v0.14
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:
- Support for Paho C v1.3.16
- Improved performance and lower latency for connect and publish operations.
- Added synchronous (blocking) and async event streams.
- All events from the client flow through the stream: Connect, Connection Lost, Disconnected, Incoming Message
- Adds some tokio examples.
- Fixed up some MQTT v5 error handling to properly report reason code errors.
For the complete list of updates and bug fixes, see the CHANGELOG
A Note on Async Runtimes
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:
- I/O operations return a simple
Futurethat are compatible with any runtime that can poll it. - Stream-style input uses async-channel's which are runtime agnostic.
- Unlike most futures, the I/O operations are started as soon as the function is called. They don't need an .await to start. Awaiting the token simply pauses the task until the operation completes.
- The legacy async API is still working under the hood, so you can still use async-style operations without an async runtime. In that case you don't use .await, but rather use the
Token::wait()functions which block the calling thread waiting for completion.
Using the Crate
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.
Build Features
The default behaviour can be altered by enabling or disabling the features:
- "default" -
[bundled, ssl] - "bundled" - Whether to build the Paho C library contained in the Git submodule under the contained paho-mqtt-sys crate. This is similar to the "vendored" feature in other Rust projects.
- "build_bindgen" - Whether to build the bindings for the target using bindgen. If not set, the build will attempt to find and use pre-built bindings for the target.
- "ssl" - Whether to enable the use of secure sockets and secure websocket connections.
- "vendored-ssl" - Whether to build OpenSSL. This passes the "vendored" option to the openssl-sys crate.
- "tokio" - Builds some tokio examples (the library is fully compatible with tokio even without this feature).
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.
Using SSL/TLS
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, andmake. -
If you don't use vendored-ssl, it will attempt to use a package manager on the build host to find the library:
pkg-configon Unix-like systems,Homebrewon macOS, andvcpkgon 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"] }
Windows
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"] }
macOS Universal Binaries
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:
$ car
