| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 |
- //
- // Copyright (c) 2023-2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_MQTT5_MQTT_CLIENT_HPP
- #define BOOST_MQTT5_MQTT_CLIENT_HPP
- #include <boost/mqtt5/error.hpp>
- #include <boost/mqtt5/logger_traits.hpp>
- #include <boost/mqtt5/types.hpp>
- #include <boost/mqtt5/detail/log_invoke.hpp>
- #include <boost/mqtt5/detail/rebind_executor.hpp>
- #include <boost/mqtt5/impl/client_service.hpp>
- #include <boost/mqtt5/impl/publish_send_op.hpp>
- #include <boost/mqtt5/impl/re_auth_op.hpp>
- #include <boost/mqtt5/impl/run_op.hpp>
- #include <boost/mqtt5/impl/subscribe_op.hpp>
- #include <boost/mqtt5/impl/unsubscribe_op.hpp>
- #include <boost/asio/async_result.hpp>
- #include <boost/system/error_code.hpp>
- #include <memory>
- #include <string>
- #include <type_traits>
- #include <variant> // std::monostate
- #include <vector>
- namespace boost::mqtt5 {
- namespace asio = boost::asio;
- /**
- * \brief \__MQTT\__ client used to connect and communicate with a Broker.
- *
- * \tparam \__StreamType\__ Type of the underlying transport protocol used to transfer
- * the stream of bytes between the Client and the Broker. The transport must be
- * ordered and lossless.
- * \tparam \__TlsContext\__ Type of the context object used in TLS/SSL connections.
- * \tparam \__LoggerType\__ Type of object used to log events within the Client.
- *
- * \par Thread safety
- * Distinct objects: safe. \n
- * Shared objects: unsafe. \n
- * This class is <b>not thread-safe</b>.
- * The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand.
- */
- template <
- typename StreamType,
- typename TlsContext = std::monostate,
- typename LoggerType = noop_logger
- >
- class mqtt_client {
- public:
- /// The executor type associated with the client.
- using executor_type = typename StreamType::executor_type;
- /// Rebinds the client type to another executor.
- template <typename Executor>
- struct rebind_executor {
- /// The client type when rebound to the specified executor.
- using other = mqtt_client<
- typename detail::rebind_executor<StreamType, Executor>::other,
- TlsContext,
- LoggerType
- >;
- };
- private:
- using stream_type = StreamType;
- using tls_context_type = TlsContext;
- using logger_type = LoggerType;
- using client_service_type = detail::client_service<
- stream_type, tls_context_type, logger_type
- >;
- using impl_type = std::shared_ptr<client_service_type>;
- impl_type _impl;
- public:
- /**
- * \brief Constructs a Client with given parameters.
- *
- * \param ex An executor that will be associated with the Client.
- * \param tls_context A context object used in TLS/SSL connection.
- * \param logger An object satisfying the \__LoggerType\__ concept used to log events within the Client.
- */
- explicit mqtt_client(
- const executor_type& ex,
- tls_context_type tls_context = {}, logger_type logger = {}
- ) :
- _impl(std::make_shared<client_service_type>(
- ex, std::move(tls_context), std::move(logger)
- ))
- {}
- /**
- * \brief Constructs a Client with given parameters.
- *
- * \tparam \__ExecutionContext\__ Type of a concrete execution context.
- * \param context Execution context whose executor will be associated with the Client.
- * \param tls_context A context object used in TLS/SSL connection.
- * \param logger An object satisfying the \__LoggerType\__ concept used to log events within the Client.
- *
- * \par Precondition
- * \code
- * std::is_convertible_v<ExecutionContext&, asio::execution_context&>
- * \endcode
- */
- template <
- typename ExecutionContext,
- std::enable_if_t<
- std::is_convertible_v<ExecutionContext&, asio::execution_context&>,
- bool
- > = true
- >
- explicit mqtt_client(
- ExecutionContext& context,
- tls_context_type tls_context = {}, logger_type logger = {}
- ) :
- mqtt_client(
- context.get_executor(),
- std::move(tls_context), std::move(logger)
- )
- {}
- /**
- * \brief Move-construct an mqtt_client from another.
- */
- mqtt_client(mqtt_client&&) noexcept = default;
- /**
- * \brief Move assignment operator.
- *
- * \details Cancels this client first.
- */
- mqtt_client& operator=(mqtt_client&& other) noexcept {
- _impl->cancel();
- _impl = std::move(other._impl);
- return *this;
- }
- /**
- * \brief Destructor.
- *
- * \details Automatically calls \ref cancel.
- */
- ~mqtt_client() {
- if (_impl)
- _impl->cancel();
- }
- /**
- * \brief Get the executor associated with the object.
- */
- executor_type get_executor() const noexcept {
- return _impl->get_executor();
- }
- /**
- * \brief Get the context object used in TLS/SSL connection.
- *
- * \note This function may only be invoked
- * when the template parameter \__TlsContext\__ was configured
- * with non-default type during the creation of a \ref mqtt_client.
- *
- * \par Precondition
- * \code
- * !std::is_same_v<TlsContext, std::monostate>
- * \endcode
- */
- template <
- typename Ctx = TlsContext,
- std::enable_if_t<!std::is_same_v<Ctx, std::monostate>, bool> = true
- >
- decltype(auto) tls_context() {
- return _impl->tls_context();
- }
- /**
- * \brief Start the Client.
- *
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (__ERROR_CODE__)
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete with
- * `boost::asio::error::operation_aborted` when the client is cancelled by calling
- * \ref async_disconnect, \ref cancel, destruction or
- * if a non-recoverable error happens during a connection attempt (e.g. access denied).
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::asio::error::operation_aborted`\n
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref cancel \n
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_run(CompletionToken&& token = {}) {
- using Signature = void (error_code);
- return asio::async_initiate<CompletionToken, Signature>(
- detail::initiate_async_run(_impl), token
- );
- }
- /**
- * \brief Cancel all asynchronous operations. This function has terminal effects.
- *
- * \details All outstanding operations will complete
- * with `boost::asio::error::operation_aborted`.
- *
- * \attention This function has terminal effects and will close the Client.
- * The Client cannot be used before calling \ref async_run again.
- */
- void cancel() {
- auto impl = _impl;
- _impl = impl->dup();
- impl->cancel();
- }
- /**
- * \brief Assign a \ref will Message.
- *
- * \details The \ref will Message that the Broker should publish
- * after the Network Connection is closed and it is not
- * closed normally.
- *
- * \attention This function takes action when the client is in a non-operational state,
- * meaning the \ref async_run function has not been invoked.
- * Furthermore, you can use this function after the \ref cancel function has been called,
- * before the \ref async_run function is invoked again.
- */
- mqtt_client& will(will will) {
- _impl->will(std::move(will));
- return *this;
- }
- /**
- * \brief Assign credentials that will be used to connect to a Broker.
- *
- * \details Credentials consist of a unique Client Identifier and, optionally,
- * a User Name and Password.
- *
- * \attention This function takes action when the client is in a non-operational state,
- * meaning the \ref async_run function has not been invoked.
- * Furthermore, you can use this function after the \ref cancel function has been called,
- * before the \ref async_run function is invoked again.
- */
- mqtt_client& credentials(
- std::string client_id,
- std::string username = "", std::string password = ""
- ) {
- _impl->credentials(
- std::move(client_id),
- std::move(username), std::move(password)
- );
- return *this;
- }
- /**
- * \brief Assign a list of Brokers that the Client will attempt to connect to.
- *
- * \details The Client will cycle through the list of hosts,
- * attempting to establish a connection with each
- * until it successfully establishes a connection.
- *
- * \param hosts List of Broker addresses and ports.
- * Address and ports are separated with a colon `:` while
- * pairs of addresses and ports are separated with a comma `,`.
- * \param default_port The default port to connect to in case the port is not
- * explicitly specified in the `hosts` list.
- *
- * \attention This function takes action when the client is in a non-operational state,
- * meaning the \ref async_run function has not been invoked.
- * Furthermore, you can use this function after the \ref cancel function has been called,
- * before the \ref async_run function is invoked again.
- *
- * \par Example
- * Some valid `hosts` string:
- *
- * \code
- * std::string valid_hosts_1 = "broker1:1883, broker2, broker3:1883";
- * std::string valid_hosts_2 = "broker1";
- * \endcode
- *
- */
- mqtt_client& brokers(std::string hosts, uint16_t default_port = 1883) {
- _impl->brokers(std::move(hosts), default_port);
- return *this;
- }
- /**
- * \brief Assign an authenticator that the Client will use for
- * \__ENHANCED_AUTH\__ on every connect to a Broker.
- * Re-authentication can be initiated by calling \ref re_authenticate.
- *
- * \param authenticator Object that will be stored (move-constructed or by reference)
- * and used for authentication. It needs to satisfy \__Authenticator\__ concept.
- *
- * \attention This function takes action when the client is in a non-operational state,
- * meaning the \ref async_run function has not been invoked.
- * Furthermore, you can use this function after the \ref cancel function has been called,
- * before the \ref async_run function is invoked again.
- *
- */
- template <typename Authenticator>
- mqtt_client& authenticator(Authenticator&& authenticator) {
- static_assert(
- detail::is_authenticator<Authenticator>,
- "The type does not satisfy the Authenticator concept"
- );
- _impl->authenticator(std::forward<Authenticator>(authenticator));
- return *this;
- }
- /**
- * \brief Assign the maximum time interval that is permitted to elapse between
- * two transmissions from the Client.
- *
- * \details A non-zero value initiates a process of sending a \__PINGREQ\__
- * packet every `seconds`. If this function is not invoked, the Client assumes
- * a \__KEEP_ALIVE\__ interval of 60 seconds.
- *
- * \param seconds Time interval in seconds.
- *
- * \note If the Server sends a \__SERVER_KEEP_ALIVE\__,
- * the Client will send a \__PINGREQ\__ packet every \__SERVER_KEEP_ALIVE\__ seconds.
- *
- * \attention This function takes action when the client is in a non-operational state,
- * meaning the \ref async_run function has not been invoked.
- * Furthermore, you can use this function after the \ref cancel function has been called,
- * before the \ref async_run function is invoked again.
- *
- */
- mqtt_client& keep_alive(uint16_t seconds) {
- _impl->keep_alive(seconds);
- return *this;
- }
- /**
- * \brief Assign \__CONNECT_PROPS\__ that will be sent in a \__CONNECT\__ packet.
- * \param props \__CONNECT_PROPS\__ sent in a \__CONNECT\__ packet.
- * \see See \__CONNECT_PROPS\__ for all eligible properties.
- */
- mqtt_client& connect_properties(connect_props props) {
- _impl->connect_properties(std::move(props));
- return *this;
- }
- /**
- * \brief Assign a property that will be sent in a \__CONNECT\__ packet.
- * \param prop The \__CONNECT_PROPS\__ property to set.
- * \param value Value that will be assigned to the property.
- *
- * \par Example
- * \code
- * client.connect_property(prop::session_expiry_interval, 40); // ok
- * client.connect_property(prop::reason_string, "reason"); // does not compile, not a CONNECT prop!
- * \endcode
- *
- * \see See \__CONNECT_PROPS\__ for all eligible properties.
- */
- template <prop::property_type p>
- mqtt_client& connect_property(
- std::integral_constant<prop::property_type, p> prop,
- prop::value_type_t<p> value
- ) {
- _impl->connect_property(prop, std::move(value));
- return *this;
- }
- /**
- * \brief Initiates \__RE_AUTHENTICATION\__
- * using the authenticator given in the \ref authenticator method.
- *
- * \note If \ref authenticator was not called, this method does nothing.
- */
- void re_authenticate() {
- detail::re_auth_op { _impl }.perform();
- }
- /**
- * \brief Retrieves the value of a specific property from the last \__CONNACK\__ packet received.
- *
- * \details The return type varies according to the property requested.
- * For all properties, the return type will be `std::optional` of their respective value type.
- * For `boost::mqtt5::prop::user_property`, the return type is
- * `std::vector<std::pair<std::string, std::string>>`.
- *
- * \param prop The \__CONNACK_PROPS\__ property value to retrieve.
- *
- * \par Example
- * \code
- * std::optional<std::string> auth_method = client.connack_property(boost::mqtt5::prop::authentication_method); // ok
- * std::optional<std::string> c_type = client.connack_property(boost::mqtt5::prop::content_type); // does not compile, not a CONNACK prop!
- * \endcode
- *
- * \see See \__CONNACK_PROPS\__ for all eligible properties.
- */
- template <prop::property_type p>
- const auto& connack_property(
- std::integral_constant<prop::property_type, p> prop
- ) const {
- return _impl->connack_property(prop);
- }
- /**
- * \brief Retrieves the \__CONNACK_PROPS\__ from the last \__CONNACK\__ packet received.
- *
- * \see See \__CONNACK_PROPS\__ for all eligible properties.
- */
- const connack_props& connack_properties() const {
- return _impl->connack_properties();
- }
- /**
- * \brief Send a \__PUBLISH\__ packet to Broker to transport an
- * Application Message.
- *
- * \tparam qos_type The \ref qos_e level of assurance for delivery.
- * \param topic Identification of the information channel to which
- * Payload data is published.
- * \param payload The Application Message that is being published.
- * \param retain The \ref retain_e flag.
- * \param props An instance of \__PUBLISH_PROPS\__.
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- * On immediate completion, invocation of the handler will be performed in a manner
- * equivalent to using \__ASYNC_IMMEDIATE\__.
- *
- * \par Handler signature
- * The handler signature for this operation depends on the \ref qos_e specified:\n
- *
- * `qos` == `qos_e::at_most_once`:
- * \code
- * void (
- * __ERROR_CODE__ // Result of operation
- * )
- * \endcode
- *
- * `qos` == `qos_e::at_least_once`:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * __REASON_CODE__, // Reason Code received from Broker.
- * __PUBACK_PROPS__ // Properties received in the PUBACK packet.
- * )
- * \endcode
- *
- * `qos` == `qos_e::exactly_once`:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * __REASON_CODE__, // Reason Code received from Broker.
- * __PUBCOMP_PROPS__ // Properties received in the PUBCOMP packet.
- * )
- * \endcode
- *
- * \par Completion condition
- * Depending on the \ref qos_e specified, the asynchronous operation will complete
- * when one of the following conditions is true:\n
- * - If `qos` == `qos_e::at_most_once` and the Client
- * has successfully written the packet to the transport. \n
- * - If `qos` == `qos_e::at_least_once` and the packet has
- * been sent and acknowledged through the reception of a \__PUBACK\__ packet.
- * - If `qos` == `qos_e::exactly_once` and the packet has
- * been sent and fully acknowledged through the reception of a \__PUBCOMP\__ packet.
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success` \n
- * - `boost::asio::error::operation_aborted` \n
- * - `boost::asio::error::no_recovery` \n
- * - \ref boost::mqtt5::client::error::malformed_packet
- * - \ref boost::mqtt5::client::error::packet_too_large
- * - \ref boost::mqtt5::client::error::pid_overrun
- * - \ref boost::mqtt5::client::error::qos_not_supported
- * - \ref boost::mqtt5::client::error::retain_not_available
- * - \ref boost::mqtt5::client::error::topic_alias_maximum_reached
- * - \ref boost::mqtt5::client::error::invalid_topic
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref cancel \n
- * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__PUBLISH\__ packet \n
- *
- */
- template <qos_e qos_type,
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_publish(
- std::string topic, std::string payload,
- retain_e retain, const publish_props& props,
- CompletionToken&& token = {}
- ) {
- using Signature = detail::on_publish_signature<qos_type>;
- return asio::async_initiate<CompletionToken, Signature>(
- detail::initiate_async_publish<client_service_type, qos_type>(_impl),
- token,
- std::move(topic), std::move(payload), retain, props
- );
- }
- /**
- * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a Subscription
- * to one or more Topics of interest.
- *
- * \details After the Subscription has been established, the Broker will send
- * PUBLISH packets to the Client to forward Application Messages that were published
- * to Topics that the Client subscribed to. The Application Messages can be received
- * with \ref mqtt_client::async_receive function.
- *
- * \param topics A list of \ref subscribe_topic of interest.
- * \param props An instance of \__SUBSCRIBE_PROPS\__.
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- * On immediate completion, invocation of the handler will be performed in a manner
- * equivalent to using \__ASYNC_IMMEDIATE\__.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * std::vector<__REASON_CODE__>, // Vector of Reason Codes indicating
- * // the Subscription result for each Topic
- * // in the SUBSCRIBE packet.
- * __SUBACK_PROPS__, // Properties received in the SUBACK packet.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has successfully sent a \__SUBSCRIBE\__ packet
- * and has received a \__SUBACK\__ response from the Broker.\n
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success` \n
- * - `boost::asio::error::no_recovery` \n
- * - `boost::asio::error::operation_aborted` \n
- * - \ref boost::mqtt5::client::error::malformed_packet
- * - \ref boost::mqtt5::client::error::packet_too_large
- * - \ref boost::mqtt5::client::error::pid_overrun
- * - \ref boost::mqtt5::client::error::invalid_topic
- * - \ref boost::mqtt5::client::error::wildcard_subscription_not_available
- * - \ref boost::mqtt5::client::error::subscription_identifier_not_available
- * - \ref boost::mqtt5::client::error::shared_subscription_not_available
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n
- * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__SUBSCRIBE\__ packet \n
- *
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_subscribe(
- const std::vector<subscribe_topic>& topics,
- const subscribe_props& props,
- CompletionToken&& token = {}
- ) {
- using Signature = void (
- error_code, std::vector<reason_code>, suback_props
- );
- return asio::async_initiate<CompletionToken, Signature>(
- detail::initiate_async_subscribe(_impl), token,
- topics, props
- );
- }
- /**
- * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a Subscription
- * to one Topic of interest.
- *
- * \details After the Subscription has been established, the Broker will send
- * \__PUBLISH\__ packets to the Client to forward Application Messages that were published
- * to Topics that the Client subscribed to. The Application Messages can be received
- * with \ref mqtt_client::async_receive function.
- *
- * \param topic A \ref subscribe_topic of interest.
- * \param props An instance of \__SUBSCRIBE_PROPS\__.
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- * On immediate completion, invocation of the handler will be performed in a manner
- * equivalent to using \__ASYNC_IMMEDIATE\__.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * std::vector<__REASON_CODE__>, // Vector of Reason Codes containing the
- * // single Subscription result for the Topic
- * // in the SUBSCRIBE packet.
- * __SUBACK_PROPS__, // Properties received in the SUBACK packet.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has successfully sent a \__SUBSCRIBE\__ packet
- * and has received a \__SUBACK\__ response from the Broker.\n
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success` \n
- * - `boost::asio::error::no_recovery` \n
- * - `boost::asio::error::operation_aborted` \n
- * - \ref boost::mqtt5::client::error::malformed_packet
- * - \ref boost::mqtt5::client::error::packet_too_large
- * - \ref boost::mqtt5::client::error::pid_overrun
- * - \ref boost::mqtt5::client::error::invalid_topic
- * - \ref boost::mqtt5::client::error::wildcard_subscription_not_available
- * - \ref boost::mqtt5::client::error::subscription_identifier_not_available
- * - \ref boost::mqtt5::client::error::shared_subscription_not_available
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n
- * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__SUBSCRIBE\__ packet \n
- *
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_subscribe(
- const subscribe_topic& topic, const subscribe_props& props,
- CompletionToken&& token = {}
- ) {
- return async_subscribe(
- std::vector<subscribe_topic> { topic }, props,
- std::forward<CompletionToken>(token)
- );
- }
- /**
- * \brief Send an \__UNSUBSCRIBE\__ packet to Broker to unsubscribe from one
- * or more Topics.
- *
- * \note The Client may still receive residual Application Messages
- * through the \ref mqtt_client::async_receive function
- * from Topics the Client just unsubscribed to.
- *
- * \param topics List of Topics to unsubscribe from.
- * \param props An instance of \__UNSUBSCRIBE_PROPS\__.
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- * On immediate completion, invocation of the handler will be performed in a manner
- * equivalent to using \__ASYNC_IMMEDIATE\__.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * std::vector<__REASON_CODE__>, // Vector of Reason Codes indicating
- * // the result of unsubscribe operation
- * // for each Topic in the UNSUBSCRIBE packet.
- * __UNSUBACK_PROPS__, // Properties received in the UNSUBACK packet.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has successfully sent an \__UNSUBSCRIBE\__ packet
- * and has received an \__UNSUBACK\__ response from the Broker.\n
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success` \n
- * - `boost::asio::error::no_recovery` \n
- * - `boost::asio::error::operation_aborted` \n
- * - \ref boost::mqtt5::client::error::malformed_packet
- * - \ref boost::mqtt5::client::error::packet_too_large
- * - \ref boost::mqtt5::client::error::pid_overrun
- * - \ref boost::mqtt5::client::error::invalid_topic
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n
- * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__UNSUBSCRIBE\__ packet \n
- *
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_unsubscribe(
- const std::vector<std::string>& topics, const unsubscribe_props& props,
- CompletionToken&& token = {}
- ) {
- using Signature = void (
- error_code, std::vector<reason_code>, unsuback_props
- );
- return asio::async_initiate<CompletionToken, Signature>(
- detail::initiate_async_unsubscribe(_impl), token,
- topics, props
- );
- }
- /**
- * \brief Send an \__UNSUBSCRIBE\__ packet to Broker to unsubscribe
- * from one Topic.
- *
- * \note The Client may still receive residual Application Messages
- * through the \ref mqtt_client::async_receive function
- * from Topics the Client just unsubscribed to.
- *
- * \param topic Topic to unsubscribe from.
- * \param props An instance of \__UNSUBSCRIBE_PROPS\__.
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- * On immediate completion, invocation of the handler will be performed in a manner
- * equivalent to using \__ASYNC_IMMEDIATE\__.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * std::vector<__REASON_CODE__>, // Vector of Reason Codes containing
- * // the result of unsubscribe operation
- * // for the Topic in the UNSUBSCRIBE packet.
- * __UNSUBACK_PROPS__, // Properties received in the UNSUBACK packet.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has successfully sent an \__UNSUBSCRIBE\__ packet
- * and has received an \__UNSUBACK\__ response from the Broker.\n
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success` \n
- * - `boost::asio::error::no_recovery` \n
- * - `boost::asio::error::operation_aborted` \n
- * - \ref boost::mqtt5::client::error::malformed_packet
- * - \ref boost::mqtt5::client::error::packet_too_large
- * - \ref boost::mqtt5::client::error::pid_overrun
- * - \ref boost::mqtt5::client::error::invalid_topic
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n
- * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__UNSUBSCRIBE\__ packet \n
- *
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_unsubscribe(
- const std::string& topic, const unsubscribe_props& props,
- CompletionToken&& token = {}
- ) {
- return async_unsubscribe(
- std::vector<std::string> { topic }, props,
- std::forward<CompletionToken>(token)
- );
- }
- /**
- * \brief Asynchronously receive an Application Message.
- *
- * \details The Client will receive and complete deliveries for all the
- * \__PUBLISH\__ packets received from the Broker throughout its lifetime.
- * The Client will store them internally in the order they were delivered.
- * Calling this function will attempt to receive an Application Message
- * from internal storage.
- *
- * \note It is only recommended to call this function if you have established
- * a successful Subscription to a Topic using the \ref async_subscribe function.
- *
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- * On immediate completion, invocation of the handler will be performed in a manner
- * equivalent to using \__POST\__.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__, // Result of operation.
- * std::string, // Topic, the origin of the Application Message.
- * std::string, // Payload, the content of the Application Message.
- * __PUBLISH_PROPS__, // Properties received in the PUBLISH packet.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has a pending Application Message in its internal storage
- * ready to be received.
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success`\n
- * - `boost::asio::error::operation_aborted`\n
- * - \ref boost::mqtt5::client::error::session_expired
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` \n
- * - `cancellation_type::partial` \n
- * - `cancellation_type::total` \n
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_receive(CompletionToken&& token = {}) {
- return _impl->async_channel_receive(std::forward<CompletionToken>(token));
- }
- /**
- * \brief Disconnect the Client by sending a \__DISCONNECT\__ packet
- * with a specified Reason Code. This function has terminal effects.
- *
- * \details The Client will attempt to send a \__DISCONNECT\__ packet to the Broker
- * with a Reason Code describing the reason for disconnection.
- * If the \__DISCONNECT\__ packet is successfully transmitted,
- * or if `5 seconds` elapsed without a successful send, the Client will terminate the connection.
- *
- * \attention This function has terminal effects and will close the Client.
- * See \ref mqtt_client::cancel.
- *
- * \param reason_code Reason Code to notify
- * the Broker of the reason for the disconnection.
- * \param props An instance of \__DISCONNECT_PROPS\__.
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__ // Result of operation.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has sent a \__DISCONNECT\__ packet.\n
- * - 5 seconds have elapsed without a successful send.\n
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success`\n
- * - `boost::asio::error::operation_aborted`[footnote
- This error code can appear if the Client fails to send the \__DISCONNECT\__ packet to the Server.
- Regardless, the connection to the Server is terminated, and the Client is cancelled.
- ]\n
- * - \ref boost::mqtt5::client::error::malformed_packet
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n
- *
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_disconnect(
- disconnect_rc_e reason_code, const disconnect_props& props,
- CompletionToken&& token = {}
- ) {
- auto impl = _impl;
- _impl = impl->dup();
- return detail::async_terminal_disconnect(
- detail::disconnect_rc_e(static_cast<uint8_t>(reason_code)),
- props, impl, std::forward<CompletionToken>(token)
- );
- }
- /**
- * \brief Disconnect the Client by sending a \__DISCONNECT\__ packet
- * with a Reason Code of reason_codes.normal_disconnection.
- * This function has terminal effects.
- *
- * \details The Client will attempt to send a \__DISCONNECT\__ packet to the Broker
- * with a Reason Code describing the reason for disconnection.
- * If the \__DISCONNECT\__ packet is successfully transmitted,
- * or if `5 seconds` elapsed without a successful send, the Client will terminate the connection.
- *
- * \attention This function has terminal effects and will close the Client.
- * See \ref mqtt_client::cancel.
- *
- * \param token Completion token that will be used to produce a
- * completion handler. The handler will be invoked when the operation completes.
- *
- * \par Handler signature
- * The handler signature for this operation:
- * \code
- * void (
- * __ERROR_CODE__ // Result of operation.
- * )
- * \endcode
- *
- * \par Completion condition
- * The asynchronous operation will complete when one of the following conditions is true:\n
- * - The Client has attempted to send a \__DISCONNECT\__ packet, regardless of whether
- * the sending was successful or not.\n
- * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n
- *
- * \par Error codes
- * The list of all possible error codes that this operation can finish with:\n
- * - `boost::system::errc::errc_t::success`\n
- * - `boost::asio::error::operation_aborted`[footnote
- This error code can appear if the Client fails to send the \__DISCONNECT\__ packet to the Server.
- Regardless, the connection to the Server is terminated, and the Client is cancelled.
- ]\n
- * - \ref boost::mqtt5::client::error::malformed_packet
- *
- * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
- *
- * \par Per-Operation Cancellation
- * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n
- * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n
- */
- template <
- typename CompletionToken =
- typename asio::default_completion_token<executor_type>::type
- >
- decltype(auto) async_disconnect(CompletionToken&& token = {}) {
- return async_disconnect(
- disconnect_rc_e::normal_disconnection,
- disconnect_props {}, std::forward<CompletionToken>(token)
- );
- }
- };
- } // end namespace boost::mqtt5
- #endif // !BOOST_MQTT5_MQTT_CLIENT_HPP
|