mirror of
https://github.com/boostorg/mqtt5.git
synced 2025-07-30 20:47:37 +02:00
[mqtt-client] add readme & license, doc fixes
Summary: resolves T13126 Reviewers: ivica Reviewed By: ivica Subscribers: miljen, iljazovic Maniphest Tasks: T13126 Differential Revision: https://repo.mireo.local/D26629
This commit is contained in:
11
LICENSE
Normal file
11
LICENSE
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Copyright (c) 2001-2023 Mireo, EU
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
141
README.md
Normal file
141
README.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
Async.MQTT5: A C++20 MQTT client based on Boost.Asio
|
||||||
|
===============================
|
||||||
|
Async.MQTT5 is a professional, industrial-grade C++20 client built on [Boost.Asio](https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio.html). This client is designed for publishing or receiving messages from an MQTT 5.0 compatible broker. Async.MQTT5 represents a comprehensive implementation of the MQTT 5.0 protocol standard, offering full support for publishing or receiving messages with QoS 0, 1, and 2.
|
||||||
|
|
||||||
|
Our clear intention is to include the Async.MQTT5 library into [Boost](https://www.boost.org/). We are actively working on it.
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
---------
|
||||||
|
The [MQTT](https://mqtt.org/) protocol is widely utilised for communication in various real-world scenarios, primarily serving as a reliable communication protocol for data transfer to and from IoT devices. While the MQTT protocol itself is relatively straightforward, integrating it into an application can be complex, especially due to the challenging implementation of message retransmission after a disconnect/reconnect sequence.
|
||||||
|
|
||||||
|
The aim of Async.MQTT5 is to provide a very simple asynchronous C++ interface for application developers. The internal client's implementation manages network and MQTT protocol details. Notably, the client does not expose connect functions (nor asynchronous connect functions); instead, network connectivity, MQTT handshake, and message retransmission are automatically handled within the client.
|
||||||
|
|
||||||
|
The Async.MQTT5 interface aligns seamlessly with the Boost.Asio asynchronous model. The client's asynchronous functions are compatible with all completion tokens supported by Boost.Asio.
|
||||||
|
|
||||||
|
Features
|
||||||
|
---------
|
||||||
|
Async.MQTT5 is a library designed with the core belief that users should focus solely on their application logic, not the network complexities.
|
||||||
|
The library attempts to embody this belief with a range of key features designed to elevate the development experience:
|
||||||
|
|
||||||
|
- **Complete TCP, TLS/SSL, and WebSocket support**
|
||||||
|
- **User-focused simplicity**: Providing an interface that is as simple as possible without compromising functionality.
|
||||||
|
- **Prioritized efficiency**: Utilising network and memory resources as efficiently as possible.
|
||||||
|
- **Minimal memory footprint**: Ensuring optimal performance in resource-constrained environments typical of IoT devices.
|
||||||
|
- **Automatic reconnect**: Automatically attempt to re-establish a connection in the event of a disconnection.
|
||||||
|
- **Fully Boost.Asio compliant**: The interfaces and implementation strategies are built upon the foundations of Boost.Asio. Boost.Asio and Boost.Beast users will have no issues understanding and integrating Async.MQTT5. Furthermore, Async.MQTT5 integrates well with any other library within the Boost.Asio ecosystem.
|
||||||
|
- **Custom allocators**: Support for custom allocators allows extra flexibility and control over the memory resources. Async.MQTT5 will use allocators associated with handlers from asynchronous functions to create instances of objects needed in the library implementation.
|
||||||
|
- **Per-Operation Cancellation**: All asynchronous operations support individual, targeted cancellation as per Asio's [Per-Operation Cancellation](https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/overview/core/cancellation.html).
|
||||||
|
- **Completion Token**: All asynchronous functions support CompletionToken, allowing for versatile usage with callbacks, coroutines, futures, and more.
|
||||||
|
- **Full implementation of MQTT 5.0 specification**
|
||||||
|
- **Support for QoS 0, QoS 1, and QoS 2**
|
||||||
|
- **Custom authentication**: Async.MQTT5 defines an interface for your own custom authenticators to perform Enhanced Authentication.
|
||||||
|
- **High availability**: Async.MQTT5 supports listing multiple Brokers within the same cluster to which the Client can connect.
|
||||||
|
In the event of a connection failure with one Broker, the Client switches to the next in the list.
|
||||||
|
- **Offline buffering**: While offline, it automatically buffers all the packets to send when the connection is re-established.
|
||||||
|
|
||||||
|
Using the library
|
||||||
|
---------
|
||||||
|
|
||||||
|
1. Download [Boost](https://www.boost.org/users/download/), and add it to your include path.
|
||||||
|
2. If you use SSL, download [OpenSSL](https://www.openssl.org/), link the library and add it to your include path.
|
||||||
|
3. Additionally, you can add Async.MQTT5's `include` folder to your include path.
|
||||||
|
|
||||||
|
You can compile the example below with the following command line:
|
||||||
|
|
||||||
|
$ clang++ -std=c++20 <source-cpp-file> -o example -I<path-to-boost> -Iinclude -pthread
|
||||||
|
|
||||||
|
Usage and API
|
||||||
|
---------
|
||||||
|
Detailed documentation is available [here](https://spacetime.mireo.com/async-mqtt5/).
|
||||||
|
|
||||||
|
The following example illustrates a simple scenario of configuring a Client and publishing an Application Message.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <boost/asio/ip/tcp.hpp>
|
||||||
|
|
||||||
|
#include <async_mqtt5.hpp>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
boost::asio::io_context ioc;
|
||||||
|
|
||||||
|
using client_type = async_mqtt5::mqtt_client<boost::asio::ip::tcp::socket>;
|
||||||
|
client_type c(ioc, "");
|
||||||
|
|
||||||
|
c.credentials("clientid", "", "")
|
||||||
|
.brokers("mqtt.broker", 1883)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
c.async_publish<async_mqtt5::qos_e::at_most_once>(
|
||||||
|
"test/mqtt-test", "hello world!",
|
||||||
|
async_mqtt5::retain_e::no, async_mqtt5::publish_props {},
|
||||||
|
[](async_mqtt5::error_code ec) {
|
||||||
|
std::cout << ec.message() << std::endl;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ioc.run();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
To see more examples, visit [Examples](https://spacetime.mireo.com/async-mqtt5/async_mqtt5/examples.html).
|
||||||
|
|
||||||
|
When to use
|
||||||
|
---------
|
||||||
|
Async.MQTT5 might be suitable for you if any of the following statements is true:
|
||||||
|
|
||||||
|
- Your application uses Boost.Asio and requires integrating a MQTT Client.
|
||||||
|
- You require asynchronous access to an MQTT Broker.
|
||||||
|
- You are developing a higher-level component that requires a connection to an MQTT Broker.
|
||||||
|
- You require a dependable and resilient MQTT Client that can automatically manage all network-related issues.
|
||||||
|
|
||||||
|
It may not be suitable for you if:
|
||||||
|
- You solely require synchronous access to an MQTT Broker.
|
||||||
|
- The MQTT Broker you are connecting to does not support the MQTT 5 version.
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
---------
|
||||||
|
Async.MQTT5 is a header-only library. To use Async.MQTT5 it requires the following:
|
||||||
|
- **C++20 capable compiler**
|
||||||
|
- **Boost 1.82 or later**. In addition to Asio, we use other header-only libraries such as Beast, Spirit, and more.
|
||||||
|
- **OpenSSL**. Only if you require an SSL connection by using [boost::asio::ssl::stream](https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/reference/ssl__stream.html).
|
||||||
|
|
||||||
|
Async.MQTT5 has been tested with the following compilers:
|
||||||
|
- clang 14.0 (Linux)
|
||||||
|
- MSVC 14.37 - Visual Studio 2022 (Windows)
|
||||||
|
|
||||||
|
Contributing
|
||||||
|
---------
|
||||||
|
When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.
|
||||||
|
|
||||||
|
You may merge a Pull Request once you have the sign-off from other developers, or you may request the reviewer to merge it for you.
|
||||||
|
|
||||||
|
License
|
||||||
|
---------
|
||||||
|
|
||||||
|
Copyright (c) 2001-2023 Mireo, EU
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
||||||
|
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
Credits
|
||||||
|
---------
|
||||||
|
|
||||||
|
Maintained and authored by [Mireo](https://www.mireo.com).
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.mireo.com"><img height="200" alt="Mireo" src="https://www.mireo.com/img/assets/mireo-logo.svg"></img></a>
|
||||||
|
</p>
|
@ -1,14 +1,14 @@
|
|||||||
[library async_mqtt5
|
[library Async.MQTT5: a C++20 MQTT client
|
||||||
[quickbook 1.7]
|
[quickbook 1.7]
|
||||||
[copyright 2023 Mireo]
|
[copyright 2023 Mireo]
|
||||||
[id async_mqtt5]
|
[id async_mqtt5]
|
||||||
[purpose MQTT C++ client library]
|
[purpose C++20 MQTT client]
|
||||||
[license
|
[license
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
(See accompanying file LICENSE_1_0.txt or copy at
|
(See accompanying file LICENSE_1_0.txt or copy at
|
||||||
[@http://www.boost.org/LICENSE_1_0.txt])
|
[@http://www.boost.org/LICENSE_1_0.txt])
|
||||||
]
|
]
|
||||||
[authors [A,B,C]]
|
[authors [Siladić, Ivica], [Iljazović, Bruno], [Šimičević, Korina]]
|
||||||
[category template]
|
[category template]
|
||||||
[category generic]
|
[category generic]
|
||||||
]
|
]
|
||||||
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
[/ MQTT ]
|
[/ MQTT ]
|
||||||
[def __MQTT__ [@https://mqtt.org/ MQTT]]
|
[def __MQTT__ [@https://mqtt.org/ MQTT]]
|
||||||
[def __Self__ Async.MQTT5]
|
[def __Self__ [@https://github.com/mireo/async-mqtt5/ Async.MQTT5]]
|
||||||
[def __Client__ [reflink2 mqtt_client `mqtt_client`]]
|
[def __Client__ [reflink2 mqtt_client `mqtt_client`]]
|
||||||
|
|
||||||
[def __UTF8_STRING_PAIR__ [mqttlink 3901013 `UTF-8 String Pair`]]
|
[def __UTF8_STRING_PAIR__ [mqttlink 3901013 `UTF-8 String Pair`]]
|
||||||
|
@ -21,7 +21,7 @@ The __Self__ interface aligns seamlessly with the __Asio__ asynchronous model.
|
|||||||
The client's asynchronous functions are compatible with all completion tokens supported by __Asio__.
|
The client's asynchronous functions are compatible with all completion tokens supported by __Asio__.
|
||||||
|
|
||||||
[heading Features]
|
[heading Features]
|
||||||
__Self__ is a C++ MQTT Client library designed with the core belief that users should focus solely on their application logic, not the network complexities. [br]
|
__Self__ is a library designed with the core belief that users should focus solely on their application logic, not the network complexities. [br]
|
||||||
The library attempts to embody this belief with a range of key features designed to elevate the development experience:
|
The library attempts to embody this belief with a range of key features designed to elevate the development experience:
|
||||||
|
|
||||||
* [*Complete TCP, TLS/SLL, and WebSocket support]
|
* [*Complete TCP, TLS/SLL, and WebSocket support]
|
||||||
@ -56,6 +56,7 @@ The following example illustrates a simple scenario of configuring a Client and
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
boost::asio::io_context ioc;
|
boost::asio::io_context ioc;
|
||||||
|
|
||||||
using client_type = async_mqtt5::mqtt_client<boost::asio::ip::tcp::socket>;
|
using client_type = async_mqtt5::mqtt_client<boost::asio::ip::tcp::socket>;
|
||||||
client_type c(ioc, "");
|
client_type c(ioc, "");
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ The following example illustrates a simple scenario of configuring a Client and
|
|||||||
.run();
|
.run();
|
||||||
|
|
||||||
c.async_publish<async_mqtt5::qos_e::at_most_once>(
|
c.async_publish<async_mqtt5::qos_e::at_most_once>(
|
||||||
"test/mqtt-test", "hello world with qos0!",
|
"test/mqtt-test", "hello world!",
|
||||||
async_mqtt5::retain_e::no, async_mqtt5::publish_props {},
|
async_mqtt5::retain_e::no, async_mqtt5::publish_props {},
|
||||||
[](async_mqtt5::error_code ec) {
|
[](async_mqtt5::error_code ec) {
|
||||||
std::cout << ec.message() << std::endl;
|
std::cout << ec.message() << std::endl;
|
||||||
@ -95,14 +96,14 @@ It may not be suitable for you if:
|
|||||||
__Self__ is a header-only library.
|
__Self__ is a header-only library.
|
||||||
To use __Self__ it requires the following:
|
To use __Self__ it requires the following:
|
||||||
|
|
||||||
* [*C++20] capable compiler.
|
* [*C++20 capable compiler]
|
||||||
* [*Boost 1.82 or later]. In addition to Asio, we use other header-only libraries such as Beast, Spirit, and more.
|
* [*Boost 1.82 or later]. In addition to Asio, we use other header-only libraries such as Beast, Spirit, and more.
|
||||||
* [*OpenSSL]. Only if you require an SSL connection by using [asioreflink ssl__stream ssl::stream].
|
* [*OpenSSL]. Only if you require an SSL connection by using [asioreflink ssl__stream ssl::stream].
|
||||||
|
|
||||||
__Self__ has been tested with the following compilers:
|
__Self__ has been tested with the following compilers:
|
||||||
|
|
||||||
* clang 14.0 (Linux)
|
* clang 14.0 (Linux)
|
||||||
* MSVC 14.3 - Visual Studio 2022 (Windows)
|
* MSVC 14.37 - Visual Studio 2022 (Windows)
|
||||||
|
|
||||||
[heading Acknowledgements]
|
[heading Acknowledgements]
|
||||||
We thank [@https://github.com/chriskohlhoff Christopher Kohlhoff] for his outstanding __Asio__ library,
|
We thank [@https://github.com/chriskohlhoff Christopher Kohlhoff] for his outstanding __Asio__ library,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <fmt/format.h>
|
#include <iostream>
|
||||||
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
#include <boost/asio/co_spawn.hpp>
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
@ -55,6 +55,7 @@ constexpr char spacetime_ca[] =
|
|||||||
;
|
;
|
||||||
|
|
||||||
void publish_qos0_openssl_tls() {
|
void publish_qos0_openssl_tls() {
|
||||||
|
std::cout << "[Test-publish-qos0-openssl-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ void publish_qos0_openssl_tls() {
|
|||||||
"test/mqtt-test", "hello world with qos0!",
|
"test/mqtt-test", "hello world with qos0!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec) {
|
[&c](error_code ec) {
|
||||||
fmt::print("[Test-publish-qos0-openssl-tls] error_code: {}\n", ec.message());
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -87,6 +88,7 @@ void publish_qos0_openssl_tls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publish_qos1_openssl_tls() {
|
void publish_qos1_openssl_tls() {
|
||||||
|
std::cout << "[Test-publish-qos1-openssl-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -109,10 +111,8 @@ void publish_qos1_openssl_tls() {
|
|||||||
"test/mqtt-test", "hello world with qos1!",
|
"test/mqtt-test", "hello world with qos1!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec, reason_code rc, puback_props) {
|
[&c](error_code ec, reason_code rc, puback_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"[Test-publish-qos1-openssl-tls] "
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
"error_code: {}, reason_code: {}\n", ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -123,6 +123,7 @@ void publish_qos1_openssl_tls() {
|
|||||||
|
|
||||||
|
|
||||||
void publish_qos2_openssl_tls() {
|
void publish_qos2_openssl_tls() {
|
||||||
|
std::cout << "[Test-publish-qos2-openssl-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -145,10 +146,8 @@ void publish_qos2_openssl_tls() {
|
|||||||
"test/mqtt-test", "hello world with qos2!",
|
"test/mqtt-test", "hello world with qos2!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"[Test-publish-qos2-openssl-tls] "
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
"error_code: {}, reason_code: {}\n", ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -159,6 +158,7 @@ void publish_qos2_openssl_tls() {
|
|||||||
|
|
||||||
|
|
||||||
void subscribe_and_receive_openssl_tls(int num_receive) {
|
void subscribe_and_receive_openssl_tls(int num_receive) {
|
||||||
|
std::cout << "[Test-subscribe-and-receive-openssl-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -193,10 +193,8 @@ void subscribe_and_receive_openssl_tls(int num_receive) {
|
|||||||
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "subscribe error_code: " << ec.message() << std::endl;
|
||||||
"[Test-subscribe-and-receive-openssl-tls] subscribe error_code: {},"
|
std::cout << "subscribe reason_code: " << codes[0].message() << std::endl;
|
||||||
" reason_code: {}\n", ec.message(), codes[0].message()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -209,11 +207,10 @@ void subscribe_and_receive_openssl_tls(int num_receive) {
|
|||||||
) {
|
) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "message " << i + 1 << "/" << num_receive << std::endl;
|
||||||
"[Test-subscribe-and-receive-openssl-tls] message {}/{}:"
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"ec: {}, topic: {}, payload: {}\n",
|
std::cout << "topic: " << topic << std::endl;
|
||||||
i + 1, num_receive, ec.message(), topic, payload
|
std::cout << "payload: " << payload << std::endl;
|
||||||
);
|
|
||||||
|
|
||||||
if (i == num_receive - 1)
|
if (i == num_receive - 1)
|
||||||
c.cancel();
|
c.cancel();
|
||||||
@ -226,6 +223,7 @@ void subscribe_and_receive_openssl_tls(int num_receive) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test_coro() {
|
void test_coro() {
|
||||||
|
std::cout << "[Test-coro-openssl-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -258,10 +256,11 @@ void test_coro() {
|
|||||||
auto [codes, props] = co_await c.async_subscribe(
|
auto [codes, props] = co_await c.async_subscribe(
|
||||||
topics, subscribe_props {}, asio::use_awaitable
|
topics, subscribe_props {}, asio::use_awaitable
|
||||||
);
|
);
|
||||||
fmt::print("Subscribe result: ({}),", codes[0].message());
|
std::cout << "subscribe reason_code: " << codes[0].message() << std::endl;
|
||||||
|
|
||||||
auto [topic, payload, rec_props] = co_await c.async_receive(asio::use_awaitable);
|
auto [topic, payload, rec_props] = co_await c.async_receive(asio::use_awaitable);
|
||||||
fmt::print("Receive from topic {}: {}\n", topic, payload);
|
std::cout << "topic: " << topic << std::endl;
|
||||||
|
std::cout << "payload: " << payload << std::endl;
|
||||||
|
|
||||||
asio::steady_timer timer(ioc);
|
asio::steady_timer timer(ioc);
|
||||||
timer.expires_from_now(std::chrono::seconds(1));
|
timer.expires_from_now(std::chrono::seconds(1));
|
||||||
|
@ -7,9 +7,9 @@ void run_websocket_tls_examples();
|
|||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
run_tcp_examples();
|
run_tcp_examples();
|
||||||
//run_openssl_tls_examples();
|
run_openssl_tls_examples();
|
||||||
//run_websocket_tcp_examples();
|
run_websocket_tcp_examples();
|
||||||
//run_websocket_tls_examples();
|
run_websocket_tls_examples();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <fmt/format.h>
|
#include <iostream>
|
||||||
|
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
|
|
||||||
@ -9,7 +9,7 @@
|
|||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
|
|
||||||
void publish_qos0_tcp() {
|
void publish_qos0_tcp() {
|
||||||
fmt::print("[Test-publish-qos0-tcp]\n");
|
std::cout << "[Test-publish-qos0-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ void publish_qos0_tcp() {
|
|||||||
"test/mqtt-test", "hello world with qos0!",
|
"test/mqtt-test", "hello world with qos0!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec) {
|
[&c](error_code ec) {
|
||||||
fmt::print("\terror_code: {}\n", ec.message());
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -36,7 +36,7 @@ void publish_qos0_tcp() {
|
|||||||
|
|
||||||
|
|
||||||
void publish_qos1_tcp() {
|
void publish_qos1_tcp() {
|
||||||
fmt::print("[Test-publish-qos1-tcp]\n");
|
std::cout << "[Test-publish-qos1-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -53,10 +53,8 @@ void publish_qos1_tcp() {
|
|||||||
"test/mqtt-test", "hello world with qos1!",
|
"test/mqtt-test", "hello world with qos1!",
|
||||||
retain_e::no, publish_props {},
|
retain_e::no, publish_props {},
|
||||||
[&c](error_code ec, reason_code rc, puback_props) {
|
[&c](error_code ec, reason_code rc, puback_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"\terror_code: {}, reason_code: {}\n",
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -65,7 +63,7 @@ void publish_qos1_tcp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publish_qos2_tcp() {
|
void publish_qos2_tcp() {
|
||||||
fmt::print("[Test-publish-qos2-tcp]\n");
|
std::cout << "[Test-publish-qos2-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -80,12 +78,10 @@ void publish_qos2_tcp() {
|
|||||||
|
|
||||||
c.async_publish<qos_e::exactly_once>(
|
c.async_publish<qos_e::exactly_once>(
|
||||||
"test/mqtt-test", "hello world with qos2!",
|
"test/mqtt-test", "hello world with qos2!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props {},
|
||||||
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"\terror_code: {}, reason_code: {}\n",
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -95,7 +91,7 @@ void publish_qos2_tcp() {
|
|||||||
|
|
||||||
|
|
||||||
void subscribe_and_receive_tcp(int num_receive) {
|
void subscribe_and_receive_tcp(int num_receive) {
|
||||||
fmt::print("[Test-subscribe-and-receive-tcp]\n");
|
std::cout << "[Test-subscribe-and-receive-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -113,10 +109,8 @@ void subscribe_and_receive_tcp(int num_receive) {
|
|||||||
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "subscribe error_code: " << ec.message() << std::endl;
|
||||||
"\tsubscribe error_code: {}, reason_code: {}\n",
|
std::cout << "subscribe reason_code: " << codes[0].message() << std::endl;
|
||||||
ec.message(), codes[0].message()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -129,10 +123,10 @@ void subscribe_and_receive_tcp(int num_receive) {
|
|||||||
) {
|
) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "message " << i + 1 << "/" << num_receive << std::endl;
|
||||||
"\tmessage {}/{}: ec: {}, topic: {}, payload: {}\n",
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
i + 1, num_receive, ec.message(), topic, payload
|
std::cout << "topic: " << topic << std::endl;
|
||||||
);
|
std::cout << "payload: " << payload << std::endl;
|
||||||
|
|
||||||
if (i == num_receive - 1)
|
if (i == num_receive - 1)
|
||||||
c.cancel();
|
c.cancel();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <fmt/format.h>
|
#include <iostream>
|
||||||
|
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
|
|
||||||
@ -11,6 +11,7 @@
|
|||||||
namespace asio = boost::asio;
|
namespace asio = boost::asio;
|
||||||
|
|
||||||
void publish_qos0_websocket_tcp() {
|
void publish_qos0_websocket_tcp() {
|
||||||
|
std::cout << "[Test-publish-qos0-websocket-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ void publish_qos0_websocket_tcp() {
|
|||||||
"test/mqtt-test", "hello world with qos0!",
|
"test/mqtt-test", "hello world with qos0!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec) {
|
[&c](error_code ec) {
|
||||||
fmt::print("[Test-publish-qos0-websocket-tcp] error_code: {}\n", ec.message());
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -40,6 +41,7 @@ void publish_qos0_websocket_tcp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publish_qos1_websocket_tcp() {
|
void publish_qos1_websocket_tcp() {
|
||||||
|
std::cout << "[Test-publish-qos1-websocket-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -59,10 +61,8 @@ void publish_qos1_websocket_tcp() {
|
|||||||
"test/mqtt-test", "hello world with qos1!",
|
"test/mqtt-test", "hello world with qos1!",
|
||||||
async_mqtt5::retain_e::no, publish_props{},
|
async_mqtt5::retain_e::no, publish_props{},
|
||||||
[&c](error_code ec, reason_code rc, puback_props) {
|
[&c](error_code ec, reason_code rc, puback_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"[Test-publish-qos1-websocket-tcp] "
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
"error_code: {}, reason_code: {}\n", ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -72,6 +72,7 @@ void publish_qos1_websocket_tcp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publish_qos2_websocket_tcp() {
|
void publish_qos2_websocket_tcp() {
|
||||||
|
std::cout << "[Test-publish-qos2-websocket-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -91,10 +92,8 @@ void publish_qos2_websocket_tcp() {
|
|||||||
"test/mqtt-test", "hello world with qos2!",
|
"test/mqtt-test", "hello world with qos2!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"[Test-publish-qos2-websocket-tcp] "
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
"error_code: {}, reason_code: {}\n", ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -105,6 +104,7 @@ void publish_qos2_websocket_tcp() {
|
|||||||
|
|
||||||
|
|
||||||
void subscribe_and_receive_websocket_tcp(int num_receive) {
|
void subscribe_and_receive_websocket_tcp(int num_receive) {
|
||||||
|
std::cout << "[Test-subscribe-and-receive-websocket-tcp]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -135,10 +135,8 @@ void subscribe_and_receive_websocket_tcp(int num_receive) {
|
|||||||
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "subscribe error_code: " << ec.message() << std::endl;
|
||||||
"[Test-subscribe-and-receive-websocket-tcp] "
|
std::cout << "subscribe reason_code: " << codes[0].message() << std::endl;
|
||||||
" error_code: {}, reason_code: {}\n", ec.message(), codes[0].message()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -150,11 +148,10 @@ void subscribe_and_receive_websocket_tcp(int num_receive) {
|
|||||||
) {
|
) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "message " << i + 1 << "/" << num_receive << std::endl;
|
||||||
"[Test-subscribe-and-receive-websocket-tcp] message {}/{}:"
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"ec: {}, topic: {}, payload: {}\n",
|
std::cout << "topic: " << topic << std::endl;
|
||||||
i + 1, num_receive, ec.message(), topic, payload
|
std::cout << "payload: " << payload << std::endl;
|
||||||
);
|
|
||||||
|
|
||||||
if (i == num_receive - 1)
|
if (i == num_receive - 1)
|
||||||
c.cancel();
|
c.cancel();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <fmt/format.h>
|
#include <iostream>
|
||||||
|
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
#include <boost/asio/ssl.hpp>
|
#include <boost/asio/ssl.hpp>
|
||||||
@ -68,6 +68,7 @@ constexpr const char spacetime_ca[] =
|
|||||||
;
|
;
|
||||||
|
|
||||||
void publish_qos0_websocket_tls() {
|
void publish_qos0_websocket_tls() {
|
||||||
|
std::cout << "[Test-publish-qos0-websocket-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -92,7 +93,7 @@ void publish_qos0_websocket_tls() {
|
|||||||
"test/mqtt-test", "hello world with qos0!",
|
"test/mqtt-test", "hello world with qos0!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec) {
|
[&c](error_code ec) {
|
||||||
fmt::print("[Test-publish-qos0-websocket-tls] error_code: {}\n", ec.message());
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -102,6 +103,7 @@ void publish_qos0_websocket_tls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publish_qos1_websocket_tls() {
|
void publish_qos1_websocket_tls() {
|
||||||
|
std::cout << "[Test-publish-qos1-websocket-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -126,10 +128,8 @@ void publish_qos1_websocket_tls() {
|
|||||||
"test/mqtt-test", "hello world with qos1!",
|
"test/mqtt-test", "hello world with qos1!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec, reason_code rc, puback_props) {
|
[&c](error_code ec, reason_code rc, puback_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"[Test-publish-qos1-websocket-tls] "
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
"error_code: {}, reason_code: {}\n", ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -139,6 +139,7 @@ void publish_qos1_websocket_tls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void publish_qos2_websocket_tls() {
|
void publish_qos2_websocket_tls() {
|
||||||
|
std::cout << "[Test-publish-qos2-websocket-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -163,10 +164,8 @@ void publish_qos2_websocket_tls() {
|
|||||||
"test/mqtt-test", "hello world with qos2!",
|
"test/mqtt-test", "hello world with qos2!",
|
||||||
retain_e::no, publish_props{},
|
retain_e::no, publish_props{},
|
||||||
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
[&c](error_code ec, reason_code rc, pubcomp_props) {
|
||||||
fmt::print(
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"[Test-publish-qos2-websocket-tls] "
|
std::cout << "reason_code: " << rc.message() << std::endl;
|
||||||
"error_code: {}, reason_code: {}\n", ec.message(), rc.message()
|
|
||||||
);
|
|
||||||
c.cancel();
|
c.cancel();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -177,6 +176,7 @@ void publish_qos2_websocket_tls() {
|
|||||||
|
|
||||||
|
|
||||||
void subscribe_and_receive_websocket_tls(int num_receive) {
|
void subscribe_and_receive_websocket_tls(int num_receive) {
|
||||||
|
std::cout << "[Test-subscribe-and-receive-websocket-tls]" << std::endl;
|
||||||
using namespace async_mqtt5;
|
using namespace async_mqtt5;
|
||||||
asio::io_context ioc;
|
asio::io_context ioc;
|
||||||
|
|
||||||
@ -212,10 +212,8 @@ void subscribe_and_receive_websocket_tls(int num_receive) {
|
|||||||
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
[](error_code ec, std::vector<reason_code> codes, suback_props) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "subscribe error_code: " << ec.message() << std::endl;
|
||||||
"[Test-subscribe-and-receive-websocket-tls] "
|
std::cout << "subscribe reason_code: " << codes[0].message() << std::endl;
|
||||||
" error_code: {}, reason_code: {}\n", ec.message(), codes[0].message()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -227,11 +225,10 @@ void subscribe_and_receive_websocket_tls(int num_receive) {
|
|||||||
) {
|
) {
|
||||||
if (ec == asio::error::operation_aborted)
|
if (ec == asio::error::operation_aborted)
|
||||||
return;
|
return;
|
||||||
fmt::print(
|
std::cout << "message " << i + 1 << "/" << num_receive << std::endl;
|
||||||
"[Test-subscribe-and-receive-websocket-tls] message {}/{}:"
|
std::cout << "error_code: " << ec.message() << std::endl;
|
||||||
"ec: {}, topic: {}, payload: {}\n",
|
std::cout << "topic: " << topic << std::endl;
|
||||||
i + 1, num_receive, ec.message(), topic, payload
|
std::cout << "payload: " << payload << std::endl;
|
||||||
);
|
|
||||||
|
|
||||||
if (i == num_receive - 1)
|
if (i == num_receive - 1)
|
||||||
c.cancel();
|
c.cancel();
|
||||||
|
Reference in New Issue
Block a user