Giter Site home page Giter Site logo

paho.mqtt.rust's Introduction

Eclipse Paho MQTT Rust Client Library

docs.rs crates.io GitHub contributors

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
    • 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
    • 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.
    • Traditional asynchronous (token/wait) API
    • Synchronous/blocking API

Requires Paho C v1.3.13, or possibly later.

Latest News

To keep up with the latest announcements for this project, follow:

Twitter: @eclipsepaho and @fmpagliughi

EMail: Eclipse Paho Mailing List

Upcoming v0.13

Work has started to revamp multiple aspects of the internal code without seriously disrupting the API. Some of this will be to hide aspects of the Paho C library that leaked into the Rust API and start the march towards a 100% Rust implementation of this library. (That won't happen too soon, but it's time to start.)

One set of breaking changes will be around the library's errors. The Paho C errors will be de-nested and made easier to match. More information will also be extracted from the C library when possible.

What's new in v0.12.3

  • The -sys crate now wraps Paho C v1.3.13, fixing several issues, including crashes on reconnect callbacks.
  • Made the C logs less verbose
  • #203 AsyncClient::server_uri() getter.
  • #202 Fix disconnect timeout (from sec to ms)

What's new in v0.12.2

  • #209 Added trace/log statements from the Paho C library to the Rust logs
  • Minor cleanup of subscriber examples.

Using the Crate

To use the library, simply add this to your application's Cargo.toml dependencies list:

paho-mqtt = "0.12"

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.

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, 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.12"

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.12", 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.12", 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.12", features=["vendored-ssl"] }

Fully Static Builds with MUSL

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 can use Casro to build your application, like:

$ cargo build --target=x86_64-unknown-linux-musl

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.12", 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"]

Minimum Supported Rust Version (MSRV)

v1.63.0

This package uses Rust Edition 2021, requiring an MSRV of 1.63.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.

Developing the Crate

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 C Library and paho-mqtt-sys

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.13. 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:

  • Build the bundled library using the pre-generated bindings and SSL (default).
  • Build the bundled library and compile a copy of OpenSSL to statically link to.
  • Build the bundled library, but regenerate the bindings at build time.
  • Use an external library, with the location specified by environment variables, generating the bindings at build time.
  • Use the pre-installed library with the pre-generated bindings.

These are chosen with cargo features, explained below.

Building the bundled Paho C library

This is the default:

$ cargo build

This will initialize and update the C library sources from Git, then use the cmake crate to build the static version of the C library, and link it in. By default, the build will use the pre-generated bindings in bindings/bindings_paho_mqtt_X_Y_Z.rs, where X_Y_Z is the currently supported library version.

The default features for the build are: ["bundled", "ssl"]

When building the bundled libraries, the bindings can also be regenerated at build-time. This is especially useful when building on uncommon/untested platforms to ensure proper bindings for that system. This is done adding the "build_bindgen" feature:

$ cargo build --features "build_bindgen"

In this case it will generate bindings based on the header files in the bundled C repository.

The cached versions of the bindings are target-specific. If the pre-generated version doesn't exist for the target, it will need to be generated.

Building the Paho C library with or without SSL/TLS

To build the Paho C library with SSL/TLS we depend on the openssl-sys crate. The openssl-sys crate supports automatically detecting OpenSSL installations, manually pointing towards an OpenSSL installation using environment variables or building and statically linking to a vendored copy of OpenSSL (see the openssl-sys documentation for all available options). To use the vendored option, please use the vendored-ssl feature which also enables the bundled and ssl features.

Building with SSL happens automatically as ssl is a default feature. It requires the OpenSSL libraries be installed for the target. If they are in a non-standard place, then the OPENSSL_DIR environment variable should be set, pointing at the top-level install path, with the .lib, .a and other library files in a lib/ directory just under the root. Use like:

$ export OPENSSL_DIR=/home/myacct/openssl

or wherever the library was installed.

The crate can also be build without SSL by using --no-default-features. For example, to build the bundled Paho C library without secure sockets:

$ cargo build --no-default-features --features "bundled"
Linking OpenSSL Statically

Enable the --vendored-ssl feature to build the crate with a compiled and statically linked copy of OpenSSL. The --vendored-ssl feature also enables the bundled and ssl features, so either of these command will work:

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

Linking to an external Paho C library

The crate can generate bindings to a copy of the Paho C library in a different location in the local file system, and link to that library.

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

The ssl feature can be omitted if it is not desired.

The location of the C library is specified through an environment variable:

PAHO_MQTT_C_DIR= ...path to install directory...

It's assumed that the headers are in an include/ directory below the one specified, and the library is in lib/ under it. This would be the case with a normal install.

Alternately, this can be expressed with individual environment variables for each of the header and library directories:

PAHO_MQTT_C_INCLUDE_DIR= ...path to headers...
PAHO_MQTT_C_LIB_DIR= ...path to library...

In this case, the headers and library can be found independently. This was necessary when building against a development tree for Paho C that used GNU Make build. This doesn't seem as necessary now that CMake is used everywhere.

Linking to an installed Paho C library

If the correct version of the Paho C library is expected to be installed on the target system, the simplest solution is to use the pre-generated bindings and specify a link to the shared Paho C library.

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

This is especially useful in a production environment where the system is well controlled, such as when working with full-system build tools like yocto or buildroot. It could be easier to build or cross-compile the packages separately.

Again, the ssl feature can be omitted if it is not desired.

This option should be used with caution when building an application that will ship independently of the target system, since it assumes a very specific version of the C library and will fail if that is not the one on the target.

Rust-C Bindings

As described above, the crate can optionally use bindgen to create the bindings to the Paho C library.

https://rust-lang-nursery.github.io/rust-bindgen/

Generating bindings each time you build the Rust crate is time consuming and uses a lot of resources. This is especially noticeable when building natively on a small target like an ARM board, or similar.

But each release of the Rust crate is build against a specific version of the Paho C library, which means that for a specific target, the bindings never change from build to build. Therefore, we can create the bindings once for a target and then use them for a speedy build after that.

The crate comes with a number of pre-built bindings for several popular targets in: paho-mqtt-sys/bindings. These are files with names in the form:

bindings_paho_mqtt_c_<version>-<target>.rs

Some of these include:

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

Bindings can be created for new versions of the Paho C library or for different target platforms using the command-line bindgen tool. For example on an x86 version of Windows using MSVC, you can re-generate the bindings like this:

$ 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

To create bindings for a different target, use the TARGET environment variable. For example, to build the 32-bit MSVC bindings for Windows on a 64-bit host, use the i686-pc-windows-msvc target:

$ 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 linker issue

Bindgen requires a relatively recent version of the Clang library installed on the system - recommended v3.9 or later. The bindgen dependencies seem, however, to seek out the oldest Clang version if multiple ones are installed on the system. On Ubuntu 14.04 or 16.04, the Clang v3.6 default might give some problems, although as the Paho builder is currently configured, it should work.

But the safest thing would be to set the LIBCLANG_PATH environment variable to point to a supported version, like:

export LIBCLANG_PATH=/usr/lib/llvm-3.9/lib

Cross-Compiling

The cmake crate automatically handles cross-compiling libraries. You'll need a C cross-compiler installed on your system. See here for more info about cross-compiling Rust, in general:

https://github.com/japaric/rust-cross

The Rust Book

For example, to do a full build for ARMv7, which includes Raspberry Pi's, BeagleBones, UDOO Neo's, and lots of other ARM maker boards:

$ cargo build --target=armv7-unknown-linux-gnueabihf --examples

This builds the main crate, the -sys crate, and it cross-compiles the Paho C library. It uses SSL, so it requires you to have a version of the SSL development library installed with the cross-compiler. If the SSL libraries are not available you can compile and link them as part of the Rust build using the --vendored-ssl feature:

$ cargo build --target=armv7-unknown-linux-gnueabihf --features="vendored-ssl" --examples

If you don't want to use SSL with the cross-compiler:

$ cargo build --target=armv7-unknown-linux-gnueabihf --no-default-features --features="bundled" --examples

If the triplet of the installed cross-compiler doesn't exactly match that of the Rust target, you might also need to correct the CC environment variable:

$ CC_armv7-unknown-linux-gnueabihf=armv7-unknown-linux-gnueabihf-gcc cargo build --target=armv7-unknown-linux-gnueabihf --features="vendored-ssl" --examples

Cross-Compiling with the "cross" project.

The cross project is a cross-compilation build tool that utilizes docker containers pre-loaded with the build tools for a number of targets. It requires Docker to be installed and running on your system.

Then build/install the cross tool:

$ cargo install cross

After that, you should be able to build the project for any of the supported targets. Just use the cross command instead of cargo.

$ cross build --target=armv7-unknown-linux-gnueabihf \
    --features=vendored-ssl --examples

Fully Static Builds with musl

With the v0.9 release and beyond, it should be fairly easy to create fully static builds of applications that use the Paho crate using the musl library and tools.

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

Logging

The Rust library uses the log crate to output debug and trace information. Applications can choose to use one of the available logger implementations or define one of their own. More information is available at:

https://docs.rs/log/0.4.0/log/

The sample applications use the environment log crate, env_logger to configure output via the RUST_LOG environment variable. To use this, the following call is specified in the samples before using any of the Rust MQTT API:

env_logger::init().unwrap();

And then the library will output information as defined by the environment. Use like:

$ 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
...

In addition, the underlying Paho C library has its own logging capabilities which can be used to trace network and protocol transactions. It is configured by the environment variables MQTT_C_CLIENT_TRACE and MQTT_C_CLIENT_TRACE_LEVEL. The former names the log file, with the special value "ON" to log to stdout. The latter specifies one of the levels: ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM.

export MQTT_C_CLIENT_TRACE=ON
export MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL

Example

Several small sample applications can be found in the examples directory. Here is what a small MQTT publisher might look like:

use std::process;

extern crate paho_mqtt as mqtt;

fn main() {
    // Create a client & define connect options
    let cli = mqtt::Client::new("tcp://localhost: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();
}

External Libraries and Utilities

Several external projects are under development which use or enhance the Paho MQTT Rust library. These can be used in a system with the Rust library or serve as further examples of it's use.

Redis Persistence

The mqtt-redis create allows the use of Redis as a persistence store. It also provides a good example of creating a user-defined persistence which implements the ClientPersistence trait. It can be found at:

https://github.com/fpagliughi/mqtt.rust.redis

paho.mqtt.rust's People

Contributors

cecton avatar cph-w avatar czocher avatar drasko avatar fbrouille avatar feelemoon avatar fpagliughi avatar jnicholls avatar nicolaskribas avatar oscarwcl avatar pabigot avatar qm3ster avatar ryankurte avatar svanharmelen avatar tiejunms avatar tobdub avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paho.mqtt.rust's Issues

Building on windows with msys and gnu toolchain fails

Sadly my attepts to get it up and running with gnu toolchain + msys on windows yielded no luck.

toolchain: stable-x86_64-pc-windows-gnu

cargo build:

cargo :    Compiling paho-mqtt-sys v0.2.1 (F:\Amazon Drive\Rust Projects\paho.mqtt.rust\paho-mqtt-sys)
At line:1 char:1
+ cargo build *>> straight.log
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (   Compiling pa...\paho-mqtt-sys):String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
error
: failed to run custom build command for `paho-mqtt-sys v0.2.1 (F:\Amazon Drive\Rust Projects\paho.mqtt.rust\paho-mqtt-sys)`

Caused by:
  process didn't exit successfully: `F:\Amazon Drive\Rust Projects\paho.mqtt.rust\target\debug\build\paho-mqtt-sys-a66e7b96c7cd6b9b\build-script-build` (exit code: 101)
--- stdout
debug:Running the bundled build for Paho C
cargo:rerun-if-changed=build.rs
running: "cmake" "F:\\Amazon Drive\\Rust Projects\\paho.mqtt.rust\\paho-mqtt-sys\\paho.mqtt.c/" "-G" "MinGW Makefiles" "-DPAHO_BUILD_STATIC=on" "-DPAHO_ENABLE_TESTING=off" "-DPAHO_WITH_SSL=on" "-DCMAKE_INSTALL_PREFIX=F:\\Amazon Drive\\Rust 
Projects\\paho.mqtt.rust\\target\\debug\\build\\paho-mqtt-sys-a3caf73975c6fe62\\out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -m64" "-DCMAKE_CXX_FLAGS= -ffunction-sections -fdata-sections -m64" "-DCMAKE_BUILD_TYPE=Debug"
-- CMake version: 3.16.0
-- CMake system name: Windows
-- Timestamp is 2019-12-30T00:52:46Z
-- OpenSSL hints: C:/OpenSSL-Win64
-- OpenSSL headers found at C:/OpenSSL-Win64/include
-- OpenSSL library found at C:/OpenSSL-Win64/lib/libssl.lib
-- OpenSSL Crypto library found at C:/OpenSSL-Win64/lib/libcrypto.lib
-- Configuring done
-- Generating done
-- Build files have been written to: F:/Amazon Drive/Rust Projects/paho.mqtt.rust/target/debug/build/paho-mqtt-sys-a3caf73975c6fe62/out/build
running: "cmake" "--build" "." "--target" "install" "--config" "Debug" "--"
[ 51%] Built target common_obj
[ 66%] Built target common_ssl_obj
Scanning dependencies of target paho-mqtt3a
Scanning dependencies of target paho-mqtt3c
Scanning dependencies of target paho-mqtt3c-static
Scanning dependencies of target paho-mqtt3cs
Scanning dependencies of target paho-mqtt3as
Scanning dependencies of target paho-mqtt3a-static
Scanning dependencies of target paho-mqtt3cs-static
Scanning dependencies of target paho-mqtt3as-static
[ 72%] Building C object src/CMakeFiles/paho-mqtt3a.dir/MQTTAsync.c.obj
[ 74%] Building C object src/CMakeFiles/paho-mqtt3c-static.dir/MQTTClient.c.obj
[ 74%] Building C object src/CMakeFiles/paho-mqtt3c.dir/MQTTClient.c.obj
[ 74%] Building C object src/CMakeFiles/paho-mqtt3cs.dir/MQTTClient.c.obj
[ 75%] Building C object src/CMakeFiles/paho-mqtt3as.dir/MQTTAsync.c.obj
[ 75%] Building C object src/CMakeFiles/paho-mqtt3a-static.dir/MQTTAsync.c.obj
[ 78%] Building C object src/CMakeFiles/paho-mqtt3as-static.dir/MQTTAsync.c.obj
[ 78%] Building C object src/CMakeFiles/paho-mqtt3cs-static.dir/MQTTClient.c.obj
[ 80%] Linking C shared library libpaho-mqtt3c.dll
[ 81%] Linking C static library libpaho-mqtt3c-static.a
[ 83%] Linking C static library libpaho-mqtt3cs-static.a
[ 84%] Linking C shared library libpaho-mqtt3a.dll
[ 86%] Linking C shared library libpaho-mqtt3cs.dll
[ 87%] Linking C static library libpaho-mqtt3a-static.a
[ 89%] Linking C static library libpaho-mqtt3as-static.a
[ 90%] Linking C shared library libpaho-mqtt3as.dll
[ 90%] Built target paho-mqtt3c-static
[ 92%] Built target paho-mqtt3cs-static
[ 92%] Built target paho-mqtt3a-static
[ 93%] Built target paho-mqtt3as-static

--- stderr
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(Base64.c.obj): in function `Base64_decode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:27: undefined reference to `__imp_CryptStringToBinaryA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(Base64.c.obj): in function `Base64_encode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:36: undefined reference to `__imp_CryptBinaryToStringA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(WebSocket.c.obj): in function `WebSocket_buildFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:232: undefined reference to `htonll'
C:/
msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(WebSocket.c.obj): in function `WebSocket_connect':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:334: undefined reference to `__imp_UuidCreate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(WebSocket.c.obj): in function `WebSocket_receiveFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:926: undefined reference to `ntohll'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [src\CMakeFiles\paho-mqtt3c.dir\build.make:130: src/libpaho-mqtt3c.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:172: src/CMakeFiles/paho-mqtt3c.dir/all] Error 2
mingw32-make.exe[1]: *** Waiting for unfinished jobs....
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(Base64.c.obj): in function `Base64_decode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:27: undefined reference to `__imp_CryptStringToBinaryA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(Base64.c.obj): in function `Base64_encode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:36: undefined reference to `__imp_CryptBinaryToStringA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(WebSocket.c.obj): in function `WebSocket_buildFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:232: undefined reference to `htonll'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(WebSocket.c.obj): in function `WebSocket_connect':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:334: undefined reference to `__imp_UuidCreate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(WebSocket.c.obj): in function `WebSocket_receiveFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:926: undefined reference to `ntohll'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [src\CMakeFiles\paho-mqtt3a.dir\build.make:130: src/libpaho-mqtt3a.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:226: src/CMakeFiles/paho-mqtt3a.dir/all] Error 2
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3cs.dir/objects.a(Base64.c.obj): in function `Base64_decode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:27: undefined reference to `__imp_CryptStringToBinaryA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3cs.dir/objects.a(Base64.c.obj): in function `Base64_encode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:36: undefined reference to `__imp_CryptBinaryToStringA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3cs.dir/objects.a(WebSocket.c.obj): in function `WebSocket_buildFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:232: undefined reference to `htonll'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3cs.dir/objects.a(WebSocket.c.obj): in function `WebSocket_connect':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:334: undefined reference to `__imp_Uui
dCreate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3cs.dir/objects.a(WebSocket.c.obj): in function `WebSocket_receiveFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:926: undefined reference to `ntohll'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [src\CMakeFiles\paho-mqtt3cs.dir\build.make:148: src/libpaho-mqtt3cs.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:280: src/CMakeFiles/paho-mqtt3cs.dir/all] Error 2
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3as.dir/objects.a(Base64.c.obj): in function `Base64_decode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:27: undefined reference to `__imp_CryptStringToBinaryA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3as.dir/objects.a(Base64.c.obj): in function `Base64_encode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:36: undefined reference to `__imp_CryptBinaryToStringA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3as.dir/objects.a(WebSocket.c.obj): in function `WebSocket_buildFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:232: undefined reference to `htonll'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3as.dir/objects.a(WebSocket.c.obj): in function `WebSocket_connect':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:334: undefined reference to `__imp_UuidCreate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3as.dir/objects.a(WebSocket.c.obj): in function `WebSocket_receiveFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:926: undefined reference to `ntohll'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [src\CMakeFiles\paho-mqtt3as.dir\build.make:148: src/libpaho-mqtt3as.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:361: src/CMakeFiles/paho-mqtt3as.dir/all] Error 2
mingw32-make.exe: *** [Makefile:151: all] Error 2
thread 'main' panicked at '
command did not execute successfully, got: exit code: 2

build script failed, must exit now', C:\Users\pucie\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.42\src\lib.rs:861:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

And cargo build --no-default-features --features "bundled" for good measure:

cargo :    Compiling paho-mqtt-sys v0.2.1 (F:\Amazon Drive\Rust Projects\paho.mqtt.rust\paho-mqtt-sys)
At line:1 char:1
+ cargo build --no-default-features --features "bundled" *>> bundled.lo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (   Compiling pa...\paho-mqtt-sys):String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
error
: failed to run custom build command for `paho-mqtt-sys v0.2.1 (F:\Amazon Drive\Rust Projects\paho.mqtt.rust\paho-mqtt-sys)`

Caused by:
  process didn't exit successfully: `F:\Amazon Drive\Rust Projects\paho.mqtt.rust\target\debug\build\paho-mqtt-sys-6f98144069b30247\build-script-build` (exit code: 101)
--- stdout
debug:Running the bundled build for Paho C
cargo:rerun-if-changed=build.rs
running: "cmake" "F:\\Amazon Drive\\Rust Projects\\paho.mqtt.rust\\paho-mqtt-sys\\paho.mqtt.c/" "-G" "MinGW Makefiles" "-DPAHO_BUILD_STATIC=on" "-DPAHO_ENABLE_TESTING=off" "-DPAHO_WITH_SSL=off" "-DCMAKE_INSTALL_PREFIX=F:\\Amazon Drive\\Rust 
Projects\\paho.mqtt.rust\\target\\debug\\build\\paho-mqtt-sys-1dbbcdc09b96172e\\out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -m64" "-DCMAKE_CXX_FLAGS= -ffunction-sections -fdata-sections -m64" "-DCMAKE_BUILD_TYPE=Debug"
-- CMake version: 3.16.0
-- CMake system name: Windows
-- Timestamp is 2019-12-30T00:52:27Z
-- Configuring done
-- Generating done
-- Build files have been written to: F:/Amazon Drive/Rust Projects/paho.mqtt.rust/target/debug/build/paho-mqtt-sys-1dbbcdc09b96172e/out/build
running: "cmake" "--build" "." "--target" "install" "--config" "Debug" "--"
[ 68%] Built target common_obj
Scanning dependencies of target paho-mqtt3c
Scanning dependencies of target paho-mqtt3c-static
Scanning dependencies of target paho-mqtt3a
Scanning dependencies of target paho-mqtt3a-static
[ 71%] Building C object src/CMakeFiles/paho-mqtt3c.dir/MQTTClient.c.obj
[ 75%] Building C object src/CMakeFiles/paho-mqtt3c-static.dir/MQTTClient.c.obj
[ 78%] Building C object src/CMakeFiles/paho-mqtt3a-static.dir/MQTTAsync.c.obj
[ 81%] Building C object src/CMakeFiles/paho-mqtt3a.dir/MQTTAsync.c.obj
[ 84%] Linking C shared library libpaho-mqtt3c.dll
[ 87%] Linking C static library libpaho-mqtt3c-static.a
[ 90%] Linking C shared library libpaho-mqtt3a.dll
[ 93%] Linking C static library libpaho-mqtt3a-static.a
[ 93%] Built target paho-mqtt3c-static
[ 93%] Built target paho-mqtt3a-static

--- stderr
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(Base64.c.obj): in function `Base64_decode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:27: undefined reference to `__imp_CryptStringToBinaryA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(Base64.c.obj): in function `Base64_encode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:36: undefined reference to `__imp_CryptBinaryToStringA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(WebSocket.c.obj): in function `WebSocket_buildFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:232: undefined reference to `htonll'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(WebSocket.c.obj): in function `WebSocket_connect':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:334: undefined reference to `__imp_UuidCreate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3c.dir/objects.a(WebSocket.c.obj): in function `WebSocket_receiveFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:926: undefined reference to `ntohll'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [src\CMakeFiles\paho-mqtt3c.dir\build.make:130: src/libpaho-mqtt3c.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:187: src/CMakeFiles/paho-mqtt3c.dir/all] Error 2
mingw32-make.exe[1]: *** Waiting for unfinished jobs....
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-
mqtt3a.dir/objects.a(Base64.c.obj): in function `Base64_decode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:27: undefined reference to `__imp_CryptStringToBinaryA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(Base64.c.obj): in function `Base64_encode':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/Base64.c:36: undefined reference to `__imp_CryptBinaryToStringA'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(WebSocket.c.obj): in function `WebSocket_buildFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:232: undefined reference to `htonll'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(WebSocket.c.obj): in function `WebSocket_connect':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:334: undefined reference to `__imp_UuidCreate'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\paho-mqtt3a.dir/objects.a(WebSocket.c.obj): in function `WebSocket_receiveFrame':
F:/Amazon Drive/Rust Projects/paho.mqtt.rust/paho-mqtt-sys/paho.mqtt.c/src/WebSocket.c:926: undefined reference to `ntohll'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[2]: *** [src\CMakeFiles\paho-mqtt3a.dir\build.make:130: src/libpaho-mqtt3a.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:214: src/CMakeFiles/paho-mqtt3a.dir/all] Error 2
mingw32-make.exe: *** [Makefile:151: all] Error 2
thread 'main' panicked at '
command did not execute successfully, got: exit code: 2

build script failed, must exit now', C:\Users\pucie\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.42\src\lib.rs:861:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

This is separate from #45 as that issue tries to build with MSVC toolchain. Any help would be greatly appreciated!

Not sure how to work with websockets?

Hey Frank, love the work you've been doing on this.

I'm working on making a Rust example for our MQTT datastream, but I get an empty error when trying to create an async client, I think it's because the protocol wss does not get recognized. Any tips?

   let host = env::args().skip(1).next().unwrap_or(
        "wss://mqtt.cloud.pozyxlabs.com:443".to_string()
    );

    // Create the client. Use an ID for a persistent session.
    // A real system should try harder to use a unique ID.
    let mut rng = rand::thread_rng();
    let random_id: u16 = rng.gen();
    let create_options = mqtt::CreateOptionsBuilder::new()
        .server_uri(host)
        .client_id(format!("pozyx-rust-mqtt-{:?}", random_id))
        .finalize();

    // Create the client connection
    let mut cli = mqtt::AsyncClient::new(create_options).unwrap_or_else(|e| {
        println!("Error creating the client: {:?}", e);
        process::exit(1);
    });

Results in
Error creating the client:

Kind regards,

Consumer only closes if app registers a connection_lost callback

Related to #48, a consumer's receiver never gets a None unless the application explicitly registers an on_connection_lost() callback. That's because the None is pushed into the stream by the low-level, initial callback, which only gets registered in AsyncClient::set_connection_lost_callback().

Async mode and non static topics (User Data)

Hello, I am using async_subscribe as an example and I faced with problem to pass my vector of topics that is able to change during runtime to on_connect_success() static callback. Can you give a advise how to solve problem that the code below demonstrates

pub struct Client {
    topics: Rc<RefCell<Vec<String>>>,
}

impl Client {
    pub fn connect(&mut self) {
        const HOST: &str = "HOST";
        const CLIENT_ID: &str = "CLIENT_ID";

        let mut cli = AsyncClientBuilder::new()
            .server_uri(&HOST)
            .client_id(&CLIENT_ID)
            .offline_buffering(true)
            .finalize();

        let conn_opts = ConnectOptionsBuilder::new()
            .keep_alive_interval(Duration::from_secs(20))
            .clean_session(true)
            .finalize();

        fn on_connect_success(cli: &AsyncClient, _msgid: u16) {
            println!("Connection succeeded");

            // TODO: Subscribe to topics ???
        }

        fn on_connect_failure(cli: &AsyncClient, _msgid: u16, rc: i32) {
            println!("Connection attempt failed with error code {}.\n", rc);
            thread::sleep(Duration::from_millis(2500));
            cli.reconnect_with_callbacks(on_connect_success,  on_connect_failure);
        };

        cli.set_connection_lost_callback(|cli: &AsyncClient| {
            println!("Connection lost. Attempting reconnect.");
            thread::sleep(Duration::from_millis(2500));
            cli.reconnect_with_callbacks(on_connect_success, on_connect_failure);
        });

        cli.set_message_callback(move |_cli,msg| {
            if let Some(msg) = msg {
                // TODO: push msg to channel
            }
        });

        println!("Connecting to the MQTT server...");
        cli.connect_with_callbacks(conn_opts, on_connect_success, on_connect_failure);
        cli.reconnect_with_callbacks(on_connect_success, on_connect_failure);

        // ...
    }
}

Automatically build the Paho C library

Currently, the Rust crate assumes that the proper version of the Paho C library is already built and installed on the system. It would be better if it checked whether this is true or not, and if not, download and build the C library. Alternately, it could always download and build the correct version into the local output directory. This should work across all supported platforms.

The supported Paho C library version is currently v1.2.0
https://github.com/eclipse/paho.mqtt.c/tree/v1.2.0

hello, I have performance problem

I have 10000 machine,
each machine send message from mqtt every 10 sec,
so I want to use this library's asynchronous subscribe with multi-thread to figure it,
my problem is

cli.set_message_callback(|_cli,msg| {
let topic = msg.get_topic().unwrap();
let payload_str = msg.get_payload_str().unwrap();
println!("Message: {} - {}", topic, payload_str);
});

Could you show the callback multi-thread? thanks.

Segmentation fault on reconnect_with_callback function (Ubuntu 18.04/Mojave)

A segmentation faults occurs when accessing the connection options (opts) in the reconnect_with_callback function when I turn off wifi or unplug ethernet.

    pub fn reconnect_with_callbacks<FS,FF>(&self,
                                           success_cb: FS,
                                           failure_cb: FF) -> Arc<Token>
        where FS: FnMut(&AsyncClient,u16) + 'static,
              FF: FnMut(&AsyncClient,u16,i32) + 'static
    {
        let connopts = {
            let lkopts = self.inner.opts.lock().unwrap();
            (*lkopts).clone()
        };
        self.connect_with_callbacks(connopts, success_cb, failure_cb)
    }

self.inner.opts.lock().unwrap() => opts is NULL

I reproduce this issue on both Ubuntu 18.04 and macos Mojave using regular asynchronous examples. The connect_with_callbacks works very well though when re-executing the program without internet.

Futures support

For the AsyncClient, it would be cool if the Token implemented Future. I am going to be doing this myself—or at least attempt it—and if I pull it off I'll upstream it.

Is it possible to use the current implementation with Futures 0.3?

Hey there, thanks so much for your work on this library 😄

I understand that Futures 0.3 support is coming later in the year, but was just curious if you have an example of using this library with Futures 0.3?

My scenario is that I would like to take each incoming message, process it and insert into a database. Of course, the main point is to avoid blocking further messages from being received.

I'm getting lots of errors about certain traits not being implemented when running against Futures 0.3 (even though I have used them). These are for traits such as and_then and for_each.

I'm still pretty new to Rust and am a bit lost if this is even possible. Any help would be greatly appreciated?

Thanks heaps
Fotis

Inbound messages have a corrupt C struct

Incoming (subscribed) messages seem to have a corrupted underlying C struct - cmsg: ffi::MQTTAsync_message. A message should look like this:

Message { cmsg: MQTTAsync_message { struct_id: [77, 81, 84, 77], struct_version: 0, payloadlen: 11, payload: 0xXXXXXXXX, qos: 0, retained: 0, dup: 0, msgid: 0 }, topic: "hello", payload: [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] }

but it arrives like this:

Message { cmsg: MQTTAsync_message { struct_id: [71, 58, 112, 97], struct_version: 1834970984, payloadlen: 11, payload: 0xXXXXXXXX, qos: 0, retained: 0, dup: 0, msgid: 0 }, topic: "hello", payload: [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] }

Note that the eye-catcher, struct_id, and the struct_version are incorrect.

This normally would have no effect if you are just processing the incoming messages, but if you attempt to re-transmit a message, the publish will fail with error -8: MQTTASYNC_BAD_STRUCTURE

Handle messages asynchronously

Hello,
thank you for the great library!

I am looking for Rust MQTT library for my application.
I want it to be able to handle incoming messages asynchronously because there will be DB interaction and other blocking things.

I played a little with async_subscribe, in particular I added thread::sleep within set_message_callback callback.
And message handling had been queued: one message was handling (i.e. waiting on sleep) and new incoming message was queued and processed only after awaking.

Is there any way to have asynchronous message handling?
Should I create some kind of a thread poll within set_message_callback and just push incoming message to that pool?
Or it will affect dealing with QoS?
As far as I understand for QoS=1 we firstly send PUBACK and then call user's callback.
Does it mean that it doesn't matter whether I would handle incoming message in the same or in separate thread because PUBACK was already sent?

Thank you.

Please make the Paho MQTT types implement `std::marker::Send`

Description
I would like to write an application that accepts incoming requests, calculates and returns the result. The calculation takes a long time, so several calculations should run in parallel and do not block other incoming requests.

A simple solution is to start a worker thread for each incoming request, which performs the computation and publishes the result when the calculation has finished.

Unfortunately, it is not possible to implement this simple pattern with Phao MQTT because the Phao types do not implement the marker trait std::marker::Send.

Note: For some reasons, I do want to use the synchronous API in my real life project.

My Request
Please make the Phao types implement std::marker::Send.

Code Example
Here's a snippet that illustrates the problem (rustc 1.30.1):

extern crate paho_mqtt;

use paho_mqtt::{Client, Message, MessageBuilder};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

fn main() {
    // create client and establish connection to broker
    let mut client = Client::new("tcp://localhost:1883").unwrap();
    client.connect(None).unwrap();

    // prepare to consume incoming requests
    let requests = client.start_consuming();
    client.subscribe("requests", 1).unwrap();

    // move client into mutex to share it with other threads
    let client = Arc::new(Mutex::new(client));

    // dispatch incoming requests, start a worker thread per request
    loop {
        let request = requests.recv().unwrap().unwrap();
        // create a thread private clone of the client protected by the mutex
        let client_clone = client.clone();
        thread::spawn(move || {    // <--- Error: "`*mut std::ffi::c_void` cannot be sent between threads safely" and more...
            // some long running operation
            let response = process_request(request);
            // publish the result
            client_clone.lock().unwrap().publish(response).unwrap();
        });
    }
}

fn process_request(request: Message) -> Message {
    thread::sleep(Duration::from_millis(3000));
    MessageBuilder::new()
        .topic("responses")
        .payload("42")
        .qos(1)
        .finalize()
}

Part of the build output:

foo@ubuntu:~/git/mqtt-send$ cargo build
   Compiling mqtt-send v0.1.0 (/home/foo/git/mqtt-send)
error[E0277]: `*mut std::ffi::c_void` cannot be sent between threads safely
  --> src/main.rs:25:9
   |
25 |         thread::spawn(move || {    // <--- Error: "`*mut std::ffi::c_void` cannot be sent between threads safely" and more...
   |         ^^^^^^^^^^^^^ `*mut std::ffi::c_void` cannot be sent between threads safely
   |
   = help: within `[closure@src/main.rs:25:23: 30:10 request:paho_mqtt::Message, client_clone:std::sync::Arc<std::sync::Mutex<paho_mqtt::Client>>]`, the trait `std::marker::Send` is not implemented for `*mut std::ffi::c_void`
   = note: required because it appears within the type `paho_mqtt_sys::MQTTAsync_message`
   = note: required because it appears within the type `paho_mqtt::Message`
   = note: required because it appears within the type `[closure@src/main.rs:25:23: 30:10 request:paho_mqtt::Message, client_clone:std::sync::Arc<std::sync::Mutex<paho_mqtt::Client>>]`
   = note: required by `std::thread::spawn`

error[E0277]: `*mut paho_mqtt_sys::MQTTClient_persistence` cannot be sent between threads safely
  --> src/main.rs:25:9
...

Successful publish doesn't signal the token as complete

It appears that there's an intermittent problem in which a successful publish does not mark the token as completed. Waiting on the token then times out. This is manifesting in the sync_publish sample app. If run ten times the error maybe occurs once or twice.

This may be a problem with the underlying Paho C library and was also reported there:
eclipse/paho.mqtt.c#657

mqtt client is creating empty folders

Folders are created with the name <client_id>-<host>-<port>. This is especially annoying when your client id is dynamic so a lot of folders get created. Also in my case the folders are empty so are they really needed? What happens on read only filesystems?

Segmentation fault on arm

I'm encountering SIGSEGV (Address boundary error) on arm while connecting to mqtt server. The same code works as expected on x86 machine.

I'm trying to run paho.mqtt on raspberry pi zero w. I cross compile using cross build --target arm-unknown-linux-gnueabi --no-default-features --features "bundled". The code snipped I used (more less) is below, as well as the debug info from rpi zero failed attempt and x86 development machine. I have tried the 0.6.0 crate and develop branch from this repo with the same result.

Adding conn_opts didn't change the result.

Code

    let mut cli = mqtt::Client::new(host).unwrap_or_else(|e| {
        println!("Error creating the client: {:?}", e);
        process::exit(1)
    });
    // Use 5sec timeouts for sync calls.
    cli.set_timeout(Duration::from_secs(5));
    println!("Connecting to host {}", host);
    // Connect and wait for it to complete or fail

    let conn_opts = mqtt::ConnectOptionsBuilder::new()
    .keep_alive_interval(Duration::from_secs(20))
    .clean_session(true)
    .finalize();

    if let Err(e) = cli.connect(conn_opts) {
        println!("Unable to connect: {:?}", e);
        process::exit(1);
    }

    println!("Connected");
    let event_msg: &str;

Error

@pizero ~> env RUST_LOG=debug ./motion-mqtt -e end
[2019-12-15T23:19:25Z DEBUG paho_mqtt::async_client] Creating client with persistence: 0
[2019-12-15T23:19:25Z DEBUG paho_mqtt::async_client] AsyncClient handle: 0x159a11c
[2019-12-15T23:19:25Z DEBUG paho_mqtt::async_client] Connecting handle: 0x159a11c
[2019-12-15T23:19:25Z DEBUG paho_mqtt::async_client] Connect options: ConnectOptions { copts: MQTTAsync_connectOptions { struct_id: [77, 81, 84, 67], struct_version: 5, keepAliveInterval: 20, cleansession: 1, maxInflight: 10, will: 0x0, username: 0x0, password: 0x0, connectTimeout: 30, retryInterval: 0, ssl: 0x0, onSuccess: None, onFailure: None, context: 0x0, serverURIcount: 0, serverURIs: 0x0, MQTTVersion: 0, automaticReconnect: 0, minRetryInterval: 1, maxRetryInterval: 60, binarypwd: MQTTAsync_connectOptions__bindgen_ty_1 { len: 0, data: 0x0 }, cleanstart: 0, connectProperties: 0x0, willProperties: 0x0, onSuccess5: None, onFailure5: None }, will: None, ssl: None, user_name: None, password: None, server_uris: StringCollection { coll: [], c_coll: [], c_mut_coll: [] } }
[2019-12-15T23:19:25Z DEBUG paho_mqtt::token] Token success! 0x15982c0, 0xb6596d60
[2019-12-15T23:19:25Z DEBUG paho_mqtt::token] Token completed with code: 0
[2019-12-15T23:19:25Z DEBUG paho_mqtt::token] Expected server response for: Connect
fish: “env RUST_LOG=debug ./motion-mqt…” terminated by signal SIGSEGV (Address boundary error)

Expected

[2019-12-15T23:21:05Z DEBUG paho_mqtt::async_client] Creating client with persistence: 0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::async_client] AsyncClient handle: 0x55ce76099264
Connecting to host tcp://rockpi.chwalisz.xyz:1883
[2019-12-15T23:21:05Z DEBUG paho_mqtt::async_client] Connecting handle: 0x55ce76099264
[2019-12-15T23:21:05Z DEBUG paho_mqtt::async_client] Connect options: ConnectOptions { copts: MQTTAsync_connectOptions { struct_id: [77, 81, 84, 67], struct_version: 5, keepAliveInterval: 20, cleansession: 1, maxInflight: 10, will: 0x0, username: 0x0, password: 0x0, connectTimeout: 30, retryInterval: 0, ssl: 0x0, onSuccess: None, onFailure: None, context: 0x0, serverURIcount: 0, serverURIs: 0x0, MQTTVersion: 0, automaticReconnect: 0, minRetryInterval: 1, maxRetryInterval: 60, binarypwd: MQTTAsync_connectOptions__bindgen_ty_1 { len: 0, data: 0x0 }, cleanstart: 0, connectProperties: 0x0, willProperties: 0x0, onSuccess5: None, onFailure5: None }, will: None, ssl: None, user_name: None, password: None, server_uris: StringCollection { coll: [], c_coll: [], c_mut_coll: [] } }
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Token success! 0x55ce7609aab0, 0x7f83cb8a3d30
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Token completed with code: 0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Expected server response for: Connect
Connected
[2019-12-15T23:21:05Z DEBUG paho_mqtt::async_client] Publish: Message { cmsg: MQTTAsync_message { struct_id: [77, 81, 84, 77], struct_version: 0, payloadlen: 2, payload: 0x55ce76079510, qos: 1, retained: 0, dup: 0, msgid: 0, properties: MQTTProperties { count: 0, max_count: 0, length: 0, array: 0x0 } }, topic: "homeassistant/pizero/input/camera", payload: [79, 78] }
[2019-12-15T23:21:05Z DEBUG paho_mqtt::response_options] Created response for token at: 0x55ce7609aab0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Token success! 0x55ce7609aab0, 0x7f83cb8a3bc0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Token completed with code: 0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Expected server response for: None
Published
[2019-12-15T23:21:05Z DEBUG paho_mqtt::async_client] Disconnecting
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Token success! 0x55ce7609aab0, 0x7f83cc0a4bc0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Token completed with code: 0
[2019-12-15T23:21:05Z DEBUG paho_mqtt::token] Expected server response for: None

segfault in paho_mqtt::async_client::Token::on_complete

Using a paho_mqtt::Client from an actix::Actor causes surprise segfaults when automatic_reconnect is specified and the initial connection fails.

Manually managing connection state appears to resolve the issue.

I'm not sure if this is an interaction with the actix/tokio runtime or a standalone issue with the library.

Backtrace from the offending thread(s):

03:43:27 [WARN] Token failure! 0x7698f8, 0x0
03:43:27 [DEBUG] paho_mqtt::async_client: Token completed with code: -1

Thread 2 "redacted" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x76b42040 (LWP 3050)]
__GI___pthread_mutex_lock (mutex=0x2820) at pthread_mutex_lock.c:67
67	pthread_mutex_lock.c: No such file or directory.
(gdb) thread apply all bt

Thread 3 (Thread 0x76341040 (LWP 3051)):
#0  0x76bfef10 in __lll_lock_wait (futex=futex@entry=0x6b3280 <mqttasync_mutex_store>, private=0) at lowlevellock.c:46
#1  0x76bf7bd4 in __GI___pthread_mutex_lock (mutex=0x6b3280 <mqttasync_mutex_store>) at pthread_mutex_lock.c:80
#2  0x004c58fe in MQTTAsync_lock_mutex (amutex=<optimized out>)
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-sys-0.2.0/paho.mqtt.c/src/MQTTAsync.c:418
#3  0x004c660c in MQTTAsync_cycle (rc=0x763409dc, timeout=1000, sock=0x763409e0)
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-sys-0.2.0/paho.mqtt.c/src/MQTTAsync.c:3029
#4  MQTTAsync_receiveThread (n=<optimized out>)
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-sys-0.2.0/paho.mqtt.c/src/MQTTAsync.c:1816
#5  0x76bf4fc4 in start_thread (arg=0x76341040) at pthread_create.c:458
#6  0x76d13038 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:76 from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 2 (Thread 0x76b42040 (LWP 3050)):
#0  __GI___pthread_mutex_lock (mutex=0x2820) at pthread_mutex_lock.c:67
#1  0x004bf2f8 in std::sys::unix::mutex::Mutex::lock::hf596dabe1f241a1c (self=0x2820)
    at /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c/src/libstd/sys/unix/mutex.rs:55
#2  std::sys_common::mutex::Mutex::raw_lock::h867ed2eb64a2c1c7 (self=0x2820)
    at /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c/src/libstd/sys_common/mutex.rs:36
#3  std::sync::mutex::Mutex$LT$T$GT$::lock::heedfcbf47011c178 (self=<optimized out>)
    at /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c/src/libstd/sync/mutex.rs:220
#4  paho_mqtt::async_client::Token::on_complete::h6aee954d4ca9c6d9 (self=0x769030, cli=0x280b, msgid=0, rc=<optimized out>, msg=...)
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-0.5.0/src/async_client.rs:233
#5  0x004bf124 in paho_mqtt::async_client::Token::on_failure::h819733d949619332 (context=<optimized out>, rsp=<optimized out>)
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-0.5.0/src/async_client.rs:225
#6  0x004c7f50 in MQTTAsync_processCommand ()
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-sys-0.2.0/paho.mqtt.c/src/MQTTAsync.c:1417
#7  MQTTAsync_sendThread (n=<optimized out>)
    at /home/ryan/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-sys-0.2.0/paho.mqtt.c/src/MQTTAsync.c:1574
---Type <return> to continue, or q <return> to quit---
#8  0x76bf4fc4 in start_thread (arg=0x76b42040) at pthread_create.c:458
#9  0x76d13038 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:76 from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Investigate safer alternative for C callbacks and providing AsyncClient as context.

In set_message_callback and set_connection_lost_callback, the call to ffi::MQTTAsync_setCallbacks() will pass a self_ptr (see here), which is a pointer derived from the &mut self reference. This can yield undefined behavior when the AsyncClient::on_message_arrived callback is invoked and casts the context back to a *mut AsyncClient, because &mut self can be invalidated with simple code such as the following:

fn create_client(broker_url: &str, client_id: &str) -> AsyncClient {
    let mut client = AsyncClient::new((broker_url, client_id)).unwrap();
    client.set_message_callback(|_, _| {});
    client
}

What happens is the AsyncClient at the time of set_message_callback will be at one address location, but is then moved back to the caller who could then relocate AsyncClient somewhere else, e.g. inside of another data structure:

let client = create_client("tcp://localhost", "blah");
let state = MyState { client };

When a message arrives and that callback is invoked by the MQTT receive thread, the self_ptr has long since been invalidated. The only way to make it work properly is by boxing up the AsyncClient. For example:

fn create_client(broker_url: &str, client_id: &str) -> Box<AsyncClient> {
    let mut client = Box::new(AsyncClient::new((broker_url, client_id)).unwrap());
    client.set_message_callback(|_, _| {});
    client
}

would work fine, and the location of the AsyncClient in memory will remain in its allocated space on the heap.

I think there could be a safer approach to handling the callbacks, e.g. with allocated channels, rather than putting the burden on the user of AsyncClient to know how the callbacks work internally.

Documentation unclear on when do you get None in incoming messages.

Channel that you get from start_consuming can get either a message or None. In example there is a code that checks if client is disconnected:

// If we get a None message, check if we got disconnected,

This implies that you can get None because of something other than disconnect event. So my question is when do you get None and why do you need to check connected status of the client?

Missing fields on build

Hi, I'm trying to build paho.mqtt.rust but I get a field missing error during compilation.

This error is against paho.mqtt.c master branch, but I also tried v1.2.x and develop with no success. What am I missing?

$ cargo test
   Compiling paho-mqtt3as-sys v0.2.0 (file:///Users/gusurita/paho.mqtt.rust/paho-mqtt3as-sys)                          
error[E0063]: missing fields `cleanstart`, `connectProperties`, `onFailure5` and 2 other fields in initializer of `MQTTAsync_connectOptions`
  --> paho-mqtt3as-sys/src/lib.rs:59:3
   |
59 |         MQTTAsync_connectOptions {
   |         ^^^^^^^^^^^^^^^^^^^^^^^^ missing `cleanstart`, `connectProperties`, `onFailure5` and 2 other fields

error[E0063]: missing fields `onFailure5`, `onSuccess5`, `properties` and 3 other fields in initializer of `MQTTAsync_responseOptions`
   --> paho-mqtt3as-sys/src/lib.rs:129:3
    |
129 |         MQTTAsync_responseOptions {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `onFailure5`, `onSuccess5`, `properties` and 3 other fields

error[E0063]: missing field `properties` in initializer of `MQTTAsync_message`
   --> paho-mqtt3as-sys/src/lib.rs:145:3
    |
145 |         MQTTAsync_message {
    |         ^^^^^^^^^^^^^^^^^ missing `properties`

error[E0063]: missing fields `onFailure5`, `onSuccess5`, `properties` and 1 other field in initializer of `MQTTAsync_disconnectOptions`
   --> paho-mqtt3as-sys/src/lib.rs:163:3
    |
163 |         MQTTAsync_disconnectOptions {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `onFailure5`, `onSuccess5`, `properties` and 1 other field

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0063`.

There is no way of detecting if session was reused with synchronous client.

When connecting if you set clean_session to false the session will be reused if server has the session. So resubscribing is unnecessary. But there is no way of detecting that so you must resubscribe anyway.

Furthermore the example is wrong. You should start consuming even before connecting the client. Because if session is reused and messages are waiting for the client those messages will arrive on connect and will be lost if you don't start consuming before.

I've only tested and explored the synchronous client so I don't know if the same holds for asynchronous client.

Support for on_connect callback

There is already in the code a function not currently used for this:

unsafe extern "C" fn on_connected(context: *mut c_void, rsp: *mut ffi::MQTTAsync_successData) {

The comments say:

We currently don't use this for anything. Rather connection completion is tracked through a token.

But there is a case in which I think this function is still useful. ConnectOptions allow for automatic reconnection. If disconnection occurs, the client does reconnect but subscriptions are lost, therefore, all subscriptions should be managed on_connect.

The workaround I'm using now is that when I detect disconnection I call cli.reconnect() and resubscribe to any topic subscribed before disconnection.

Fedora / lib64 build error

I am using paho 0.6.0. Running cargo update updated paho-mqtt-sys from 0.2.1 to 0.2.2 and now the build fails:

error: failed to run custom build command for `paho-mqtt-sys v0.2.2`

Caused by:
  process didn't exit successfully: `/home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-669c04b9d659fcb7/build-script-build` (exit code: 103)
--- stdout
debug:Running the bundled build for Paho C
cargo:rerun-if-changed=build.rs
running: "cmake" "/home/matt/.cargo/registry/src/github.com-1ecc6299db9ec823/paho-mqtt-sys-0.2.2/paho.mqtt.c/" "-DPAHO_BUILD_SHARED=off" "-DPAHO_BUILD_STATIC=on" "-DPAHO_ENABLE_TESTING=off" "-DPAHO_WITH_SSL=on" "-DCMAKE_INSTALL_PREFIX=/home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_C_COMPILER=/usr/bin/cc" "-DCMAKE_CXX_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_CXX_COMPILER=/usr/bin/c++" "-DCMAKE_BUILD_TYPE=Debug"
-- CMake version: 3.17.1
-- CMake system name: Linux
-- Timestamp is 2020-04-28T16:22:32Z
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/build
running: "cmake" "--build" "." "--target" "install" "--config" "Debug" "--"
[ 39%] Built target common_obj_static
[ 79%] Built target common_ssl_obj_static
Scanning dependencies of target paho-mqtt3a-static
Scanning dependencies of target paho-mqtt3c-static
Scanning dependencies of target paho-mqtt3cs-static
Scanning dependencies of target paho-mqtt3as-static
[ 81%] Building C object src/CMakeFiles/paho-mqtt3c-static.dir/MQTTClient.c.o
[ 84%] Building C object src/CMakeFiles/paho-mqtt3cs-static.dir/MQTTClient.c.o
[ 84%] Building C object src/CMakeFiles/paho-mqtt3a-static.dir/MQTTAsync.c.o
[ 86%] Building C object src/CMakeFiles/paho-mqtt3as-static.dir/MQTTAsync.c.o
[ 87%] Linking C static library libpaho-mqtt3c.a
[ 87%] Built target paho-mqtt3c-static
[ 89%] Linking C static library libpaho-mqtt3cs.a
[ 91%] Linking C static library libpaho-mqtt3a.a
[ 93%] Built target paho-mqtt3cs-static
[ 93%] Built target paho-mqtt3a-static
[ 94%] Linking C executable MQTTVersion-static
[ 96%] Linking C static library libpaho-mqtt3as.a
[ 98%] Built target MQTTVersion-static
[100%] Built target paho-mqtt3as-static
Install the project...
-- Install configuration: "Debug"
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/MQTTAsync_publish.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/MQTTAsync_subscribe.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/MQTTClient_publish.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/MQTTClient_publish_async.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/MQTTClient_subscribe.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/paho_c_pub.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/paho_c_sub.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/paho_cs_pub.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/paho_cs_sub.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/samples/pubsub_opts.c
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/CONTRIBUTING.md
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/epl-v20
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/edl-v10
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/README.md
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/share/doc/Eclipse Paho C/notice.html
-- Installing: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib64/libpaho-mqtt3c.a
-- Installing: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib64/libpaho-mqtt3a.a
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTAsync.h
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTClient.h
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTClientPersistence.h
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTProperties.h
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTReasonCodes.h
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTSubscribeOpts.h
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/include/MQTTExportDeclarations.h
-- Installing: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib64/libpaho-mqtt3cs.a
-- Installing: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib64/libpaho-mqtt3as.a
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfig.cmake
-- Installing: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfig-debug.cmake
-- Up-to-date: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib/cmake/eclipse-paho-mqtt-c/eclipse-paho-mqtt-cConfigVersion.cmake
cargo:root=/home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out
debug:CMake output dir: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out
debug:link Using SSL library
debug:Using Paho C library at: /home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib/libpaho-mqtt3as.a
Error building Paho C library: '/home/matt/workspace/git/vi-dvr/target/debug/build/paho-mqtt-sys-d3ac7b8c19791201/out/lib/libpaho-mqtt3as.a'

--- stderr
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

warning: build failed, waiting for other jobs to finish...
error: build failed

Cargo.toml:

paho-mqtt = {version = "0.6", default-features = false, features = ["bundled"]}

persistence_ptr is a raw pointer why I believe it could be a Box

Hi,

I was looking into the PR #11 and I noticed the drop called inside a drop, which I believe is unnecessary:

drop(Box::from_raw(self.persistence_ptr));

Similarly, I was trying to figure out why that drop and I realized that persistence_ptr is a raw pointer in AsyncClient: (

persistence_ptr: *mut ffi::MQTTClient_persistence,
), while I believe it could be a simple Box, simplifying a lot the drop and removing a source of unsafeness.

Is there a reason why we use that raw pointer? Maybe is something I am overlooking... I can provide a PR to make it a Box, if you guys need.

MQTT v5 Support

The Paho C library was recently upgraded to v1.3. This is actually a large set of changes. It incorporates the updates to the new version of MQTT v5, and also adds WebSockets support.

My plan had been to first get a version of this Rust library stable operating with MQTT v3.1 (via Paho C v1.2.1). And only after that was complete to move on to MQTT v5 support.

This work is beginning now...

Consumer notification of disconnect

Currently the consumer channel is not notified if the client loses connection to the broker. The client might be left hanging if a disconnect occurs.

let rx = cli.start_consuming();
for msg in rx.iter() {
    // This should break on a disconnect
}
// The client can reconnect here

Can't build on windows.

I'm trying to cargo build on my machine but without success and the errors I get are not conveying any info.

OpenSSL :

openssl.exe version
OpenSSL 1.1.1a  20 Nov 2018

  • cargo build backtrace:
λ cargo build
    Updating crates.io index
  Downloaded env_logger v0.3.5
  Downloaded regex v0.1.80
  Downloaded regex-syntax v0.3.9
  Downloaded aho-corasick v0.5.3
  Downloaded utf8-ranges v0.1.3
  Downloaded thread_local v0.2.7
  Downloaded memchr v0.1.11
  Downloaded thread-id v2.0.0
   Compiling winapi-build v0.1.1
   Compiling libc v0.2.58
   Compiling winapi v0.2.8
   Compiling cc v1.0.37
   Compiling cfg-if v0.1.9
   Compiling regex-syntax v0.3.9
   Compiling utf8-ranges v0.1.3
   Compiling log v0.4.6
   Compiling kernel32-sys v0.2.2
   Compiling log v0.3.9
   Compiling memchr v0.1.11
   Compiling aho-corasick v0.5.3
   Compiling cmake v0.1.40
   Compiling paho-mqtt-sys v0.2.0 (C:\Users\test\paho.mqtt.rust\paho-mqtt-sys)
error: failed to run custom build command for `paho-mqtt-sys v0.2.0 (C:\Users\test\paho.mqtt.rust\paho-mqtt-sys)`
process didn't exit successfully: `C:\Users\test\paho.mqtt.rust\target\debug\build\paho-mqtt-sys-33fc5333b7858bbe\build-script-build` (exit code: 101)
--- stderr
CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_BUILD_TYPE
    CMAKE_CXX_FLAGS
    CMAKE_CXX_FLAGS_DEBUG


thread 'main' panicked at '
command did not execute successfully, got: exit code: 1

build script failed, must exit now', C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.40\src\lib.rs:832:5
stack backtrace:
   0: std::sys::windows::backtrace::set_frames
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys\windows\backtrace\mod.rs:94
   1: std::sys::windows::backtrace::unwind_backtrace
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys\windows\backtrace\mod.rs:81
   2: std::sys_common::backtrace::_print
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys_common\backtrace.rs:70
   3: std::sys_common::backtrace::print
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\sys_common\backtrace.rs:58
   4: std::panicking::default_hook::{{closure}}
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:200
   5: std::panicking::default_hook
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:215
   6: std::panicking::rust_panic_with_hook
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:478
   7: std::panicking::continue_panic_fmt
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:385
   8: std::panicking::begin_panic_fmt
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:340
   9: cmake::fail
             at C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.40\src\lib.rs:832
  10: cmake::run
             at C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.40\src\lib.rs:810
  11: cmake::Config::build
             at C:\Users\test\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.40\src\lib.rs:719
  12: build_script_build::build::main
             at .\build.rs:149
  13: build_script_build::main
             at .\build.rs:57
  14: std::rt::lang_start::{{closure}}<()>
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
  15: std::rt::lang_start_internal::{{closure}}
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs:49
  16: std::panicking::try::do_call<closure,i32>
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:297
  17: panic_unwind::__rust_maybe_catch_panic
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libpanic_unwind\lib.rs:92
  18: std::panicking::try
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panicking.rs:276
  19: std::panic::catch_unwind
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\panic.rs:388
  20: std::rt::lang_start_internal
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\/src\libstd\rt.rs:48
  21: std::rt::lang_start<()>
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858\src\libstd\rt.rs:64
  22: main
  23: invoke_main
             at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
  24: __scrt_common_main_seh
             at d:\agent\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
  25: BaseThreadInitThunk
  26: RtlUserThreadStart

warning: build failed, waiting for other jobs to finish...
error: build failed

paho Rust slower than paho Python?

I have an application implemented in both Rust and Python using the paho mqtt libraries for each language.
The app is receiving around 800 mqtt messages per second and then triggering http calls for a few of the messages based on some simple parsing.
The Rust version is using the futures API with tokio 0.2. The Python version is using PyPy3.6 v7.3.0.
For some reason the Rust version is using 50% more cpu than the Python version (running on AWS T3 instance). This was a bit surprising to me as I expected the Rust version to consume less resources.

flamegraph.svg.gz

build with musl

Hello, I tried to compile some examples with rust-musl-builder but it seems to be not working.

  1. first try
rust-musl-builder cargo build --example futures_consume --release
  1. second try
rust-musl-builder cargo build --example futures_consume --release  --features "build_bindgen"

is there a workaround?

paho.mqtt.rust doesn't build

Hello,
I tried using this library on two different operating systems (Fedora x86-64 and Linux Mint x86-64) and it failed to compile on both of them.
The reason is quite simple, the Paho MQTT C library compiles the objects to a lib64 directory while it seems something expects the objects to be in a lib directory. Renaming the directories is enough to fix this issue.

How to recreate the issue:

  1. Create an empty cargo project with paho-mqtt = "0.5.0" as the only dependency
  2. Run cargo build

Result:

debug:link Using SSL library
Error building Paho C library: '/home/czocher/Projekty/voltest/target/debug/build/paho-mqtt-sys-90be9605fd112918/out/lib/libpaho-mqtt3as-static.a'

--- stderr
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

Copying /home/czocher/Projekty/voltest/target/debug/build/paho-mqtt-sys-90be9605fd112918/out/lib64/libpaho-mqtt3as-static.a to /home/czocher/Projekty/voltest/target/debug/build/paho-mqtt-sys-90be9605fd112918/out/lib/libpaho-mqtt3as-static.a fixes the issue.

My attempt to test this issue is in #30

macos mojave build issue

running cargo build --examples fails with this error which I can't for the life of me solve.

= note: Undefined symbols for architecture x86_64: "_X509_check_host", referenced from: _SSLSocket_connect in libpaho_mqtt_sys-2049afa2e25264ee.rlib(SSLSocket.c.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

I have openssl installed with homebrew and I have no issues with other libraries using it. my python binding of Paho works fine as well

Target-specific bindings

The pre-generated bindings were created on an x86_64 Linux machine. These are in paho-mqtt-sys/bindings/bindings_paho_mqtt_c_<version>.rs.

There seems to be problems using these bindings with other targets, particularly 32-bit ones, such as ARM v7 (RPi, BeagleBone, etc). The different word size causes mis-alignment of the C structs passed back and forth from the Paho C lib, and in the case of structs containing pointers, these get junk values causing segfaults.

The quick-fix, for now, is for client applications to use the "build_bindgen" feature of the library to always regenerate the bindings on every build.

A better fix, going forward might be to use target-specific bindings like *bindings_paho_mqtt_v_<version>-<target>.rs, like:

bindings_paho_mqtt_c_1.3.1-armv7-unknown-linux-gnueabihf.rs

The problem with this approach is that bindings need to be produced for every possible target in order for the default build to always succeed.

Missing options to connect to AWS IoT Core using websockets

It looks like this package is maybe missing some options to make it possible to connect to AWS IoT Core using websockets. I noticed that in the Python version there is a ws_set_options method, is there something similar for the Rust version that I might be overlooking?

When connecting to IoT Core using websockets it requires a few extra things (headers and a path). See here for a full Python example: https://github.com/eclipse/paho.mqtt.python/blob/master/examples/aws_iot.py

Would be great to understand if this can (or already is) supported in Rust too. Or (when not) if it should be possible to add it, as then I can maybe take a stab at it... Thanks!

buffer overflow detected

hello
I use this library send message 10000/sec,
after 10 minutes get the message
how could I change buffer size?

*** buffer overflow detected ***: target/release/test_nms terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f4c71ed67e5]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7f4c71f7756c]
/lib/x86_64-linux-gnu/libc.so.6(+0x116570)[0x7f4c71f75570]
/lib/x86_64-linux-gnu/libc.so.6(+0x115ad9)[0x7f4c71f74ad9]
/lib/x86_64-linux-gnu/libc.so.6(_IO_default_xsputn+0x80)[0x7f4c71eda6b0]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0xc90)[0x7f4c71eace00]
/lib/x86_64-linux-gnu/libc.so.6(__vsprintf_chk+0x84)[0x7f4c71f74b64]
/lib/x86_64-linux-gnu/libc.so.6(__sprintf_chk+0x7d)[0x7f4c71f74abd]
/usr/local/lib/libpaho-mqtt3as.so.1(+0x8e7e)[0x7f4c72a6fe7e]
/usr/local/lib/libpaho-mqtt3as.so.1(MQTTAsync_send+0x204)[0x7f4c72a73512]
/usr/local/lib/libpaho-mqtt3as.so.1(MQTTAsync_sendMessage+0x98)[0x7f4c72a735f1]
target/release/test_nms(+0x3c957)[0x5614838f9957]
target/release/test_nms(+0x33d35)[0x5614838f0d35]
target/release/test_nms(+0x13d43)[0x5614838d0d43]
target/release/test_nms(+0x18c53)[0x5614838d5c53]
target/release/test_nms(+0x97a6d)[0x561483954a6d]
target/release/test_nms(+0x2736c)[0x5614838e436c]
target/release/test_nms(+0x8fd0c)[0x56148394cd0c]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7f4c724456ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f4c71f6582d]
======= Memory map: ========
5614838bd000-5614839dc000 r-xp 00000000 08:01 8010638 /home/damody/rust/test_nms/target/release/test_nms
561483bdb000-561483be5000 r--p 0011e000 08:01 8010638 /home/damody/rust/test_nms/target/release/test_nms
561483be5000-561483be6000 rw-p 00128000 08:01 8010638 /home/damody/rust/test_nms/target/release/test_nms
561483be6000-561483be7000 rw-p 00000000 00:00 0
7f46967eb000-7f46967ec000 ---p 00000000 00:00 0
7f46967ec000-7f46969ec000 rw-p 00000000 00:00 0
7f46969ec000-7f46969ed000 ---p 00000000 00:00 0
7f46969ed000-7f4696bed000 rw-p 00000000 00:00 0
7f4696bed000-7f4696bee000 ---p 00000000 00:00 0
7f4696bee000-7f4696dee000 rw-p 00000000 00:00 0
7f4696dee000-7f4696def000 ---p 00000000 00:00 0
7f4696def000-7f4696fef000 rw-p 00000000 00:00 0
7f4696fef000-7f4696ff0000 ---p 00000000 00:00 0
7f4696ff0000-7f46971f0000 rw-p 00000000 00:00 0
7f46971f0000-7f46971f1000 ---p 00000000 00:00 0
7f46971f1000-7f46973f1000 rw-p 00000000 00:00 0
7f46973f1000-7f46973f2000 ---p 00000000 00:00 0

AsyncClient does not have MQTTAsync_destroy called on drop

It appears the AsyncClient leaks memory when it is dropped, as the underlying MQTTAsync_destroy function is not called for the handle inside the AsyncClient. In addition to cleaning up its internal memory allocations, it would also ensure the client properly is disconnected and shut down and not just left hanging open.

User name and password should use Option<>

In the ConnectOptions struct, the user name and password are cached as CString values. They should be kept as Option<Cstring> to distinguish between an unused name/password - passed as a NULL pointer - and an empty name/password - passed as an empty, but valid string.

CPU spinning @ 100%

I am not sure if this is the way the C client always behaves, but I am seeing the i/o thread for the mqtt client spin at 100% when I create an AsyncClient instance. I would have expected this thread to utilize epoll and block, waiting for events from the kernel when the socket is available to read/write. Please advise! Is this the way the C client always works, or are we missing something in our Rust bindings to make it behave as my expectation above?

In the meantime, I will investigate the C code to understand just what is happening under the hood.

EDIT: I am using a newer master copy of the C client, not the latest v1.2.1 release. I will downgrade and test the older/stable version. I also noticed it used select rather than more performant apis, but given this is a client and there won’t be many connections, that is sufficient.

option to disable server cert auth

Hi currently there is no way to disable server cert authentication which we need to do at our workplace, I would like to add a function to the ssl_options module

pub fn enable_server_cert_auth(&mut self, enable_server_cert_auth: bool) -> &mut SslOptionsBuilder {
    self.enable_server_cert_auth = enable_server_cert_auth;
    self
}

At the same time I could add some of the other tests that currently have todos in the same module

Cannot pass `OPENSSL_SEARCH_PATH` needed for cross-compilation

Paho MQTT lib demands OPENSSL_SEARCH_PATH env variable as described here in order to pick correct cross-compiled OpenSSL lib.

However, looking at here it looks that it is impossible to pass this information to a build today.

Without this possibility, it is impossible to execute cross-compile.

Automated code review for Eclipse Paho MQTT Rust Client Library

Hi!
I am a member of the team developing monocodus — a service that performs automatic code review of GitHub pull requests to help organizations ensure a high quality of code.
We’ve developed some useful features to the moment, and now we’re looking for early users and feedback to find out what we should improve and which features the community needs the most.

We ran monocodus on a pre-created fork of your repo on GitHub https://github.com/monocodus-demonstrations/paho.mqtt.rust/pulls, and it found potential formatting issue. I hope that this information will be useful to you and would be happy to receive any feedback here or on my email [email protected].

If you want to try our service, feel free to follow the link: https://www.monocodus.com
The service is entirely free of charge for open source projects. Hope you’ ll like it :)

Add option to link SSL libs statically

Currently it is not possible to link SSL libs on or for Linux systems statically.

Please add configuration option to enable static linking.

Proposal (based on tag 0.7.1):

diff --git a/paho-mqtt-sys/build.rs b/paho-mqtt-sys/build.rs
index 9c4a942..8af5dce 100644
--- a/paho-mqtt-sys/build.rs
+++ b/paho-mqtt-sys/build.rs
@@ -175,6 +175,7 @@
     use std::path::Path;
     use std::process::Command;
     use std::env;
+    use std::str::FromStr;
 
     pub fn main() {
         println!("debug:Running the bundled build for Paho C");
@@ -250,9 +251,19 @@
 
         // Link in the SSL libraries if configured for it.
         if cfg!(feature = "ssl") {
+            let ssl_link_static = match env::var("OPENSSL_LINK_STATIC") {
+                Ok(value) => bool::from_str(value.as_str()).unwrap(),
+                Err(_) => cfg!(windows),
+            };
+
+            let ssl_link_kind = match ssl_link_static {
+                true => "static",
+                false => "dylib",
+            };
+
             if cfg!(windows) {
-                println!("cargo:rustc-link-lib=libssl");
-                println!("cargo:rustc-link-lib=libcrypto");
+                println!("cargo:rustc-link-lib={}=libssl", ssl_link_kind);
+                println!("cargo:rustc-link-lib={}=libcrypto", ssl_link_kind);
                 if let Ok(ssl_sp) = env::var("OPENSSL_ROOT_DIR") {
                     println!("cargo:rustc-link-search={}\\lib", ssl_sp);
                 }
@@ -265,8 +276,8 @@
                 };
             }
             else {
-                println!("cargo:rustc-link-lib=ssl");
-                println!("cargo:rustc-link-lib=crypto");
+                println!("cargo:rustc-link-lib={}=ssl", ssl_link_kind);
+                println!("cargo:rustc-link-lib={}=crypto", ssl_link_kind);
                 if let Ok(ssl_sp) = env::var("OPENSSL_ROOT_DIR") {
                     println!("cargo:rustc-link-search={}/lib", ssl_sp);
                 }
@@ -340,4 +351,3 @@
         bindings::place_bindings(&Path::new(&inc_dir));
     }
 }
-

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.