![]() |
|
|||
File indexing completed on 2025-09-17 08:38:23
0001 // 0002 // Copyright (c) 2023-2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. 0005 // (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 0008 #ifndef BOOST_MQTT5_MQTT_CLIENT_HPP 0009 #define BOOST_MQTT5_MQTT_CLIENT_HPP 0010 0011 #include <boost/mqtt5/error.hpp> 0012 #include <boost/mqtt5/logger_traits.hpp> 0013 #include <boost/mqtt5/types.hpp> 0014 0015 #include <boost/mqtt5/detail/log_invoke.hpp> 0016 #include <boost/mqtt5/detail/rebind_executor.hpp> 0017 0018 #include <boost/mqtt5/impl/client_service.hpp> 0019 #include <boost/mqtt5/impl/publish_send_op.hpp> 0020 #include <boost/mqtt5/impl/re_auth_op.hpp> 0021 #include <boost/mqtt5/impl/run_op.hpp> 0022 #include <boost/mqtt5/impl/subscribe_op.hpp> 0023 #include <boost/mqtt5/impl/unsubscribe_op.hpp> 0024 0025 #include <boost/asio/async_result.hpp> 0026 #include <boost/system/error_code.hpp> 0027 0028 #include <memory> 0029 #include <string> 0030 #include <type_traits> 0031 #include <variant> // std::monostate 0032 #include <vector> 0033 0034 namespace boost::mqtt5 { 0035 0036 namespace asio = boost::asio; 0037 0038 /** 0039 * \brief \__MQTT\__ client used to connect and communicate with a Broker. 0040 * 0041 * \tparam \__StreamType\__ Type of the underlying transport protocol used to transfer 0042 * the stream of bytes between the Client and the Broker. The transport must be 0043 * ordered and lossless. 0044 * \tparam \__TlsContext\__ Type of the context object used in TLS/SSL connections. 0045 * \tparam \__LoggerType\__ Type of object used to log events within the Client. 0046 * 0047 * \par Thread safety 0048 * Distinct objects: safe. \n 0049 * Shared objects: unsafe. \n 0050 * This class is <b>not thread-safe</b>. 0051 * The application must also ensure that all asynchronous operations are performed within the same implicit or explicit strand. 0052 */ 0053 template < 0054 typename StreamType, 0055 typename TlsContext = std::monostate, 0056 typename LoggerType = noop_logger 0057 > 0058 class mqtt_client { 0059 public: 0060 /// The executor type associated with the client. 0061 using executor_type = typename StreamType::executor_type; 0062 0063 /// Rebinds the client type to another executor. 0064 template <typename Executor> 0065 struct rebind_executor { 0066 /// The client type when rebound to the specified executor. 0067 using other = mqtt_client< 0068 typename detail::rebind_executor<StreamType, Executor>::other, 0069 TlsContext, 0070 LoggerType 0071 >; 0072 }; 0073 0074 private: 0075 using stream_type = StreamType; 0076 using tls_context_type = TlsContext; 0077 using logger_type = LoggerType; 0078 0079 using client_service_type = detail::client_service< 0080 stream_type, tls_context_type, logger_type 0081 >; 0082 using impl_type = std::shared_ptr<client_service_type>; 0083 impl_type _impl; 0084 0085 public: 0086 /** 0087 * \brief Constructs a Client with given parameters. 0088 * 0089 * \param ex An executor that will be associated with the Client. 0090 * \param tls_context A context object used in TLS/SSL connection. 0091 * \param logger An object satisfying the \__LoggerType\__ concept used to log events within the Client. 0092 */ 0093 explicit mqtt_client( 0094 const executor_type& ex, 0095 tls_context_type tls_context = {}, logger_type logger = {} 0096 ) : 0097 _impl(std::make_shared<client_service_type>( 0098 ex, std::move(tls_context), std::move(logger) 0099 )) 0100 {} 0101 0102 /** 0103 * \brief Constructs a Client with given parameters. 0104 * 0105 * \tparam \__ExecutionContext\__ Type of a concrete execution context. 0106 * \param context Execution context whose executor will be associated with the Client. 0107 * \param tls_context A context object used in TLS/SSL connection. 0108 * \param logger An object satisfying the \__LoggerType\__ concept used to log events within the Client. 0109 * 0110 * \par Precondition 0111 * \code 0112 * std::is_convertible_v<ExecutionContext&, asio::execution_context&> 0113 * \endcode 0114 */ 0115 template < 0116 typename ExecutionContext, 0117 std::enable_if_t< 0118 std::is_convertible_v<ExecutionContext&, asio::execution_context&>, 0119 bool 0120 > = true 0121 > 0122 explicit mqtt_client( 0123 ExecutionContext& context, 0124 tls_context_type tls_context = {}, logger_type logger = {} 0125 ) : 0126 mqtt_client( 0127 context.get_executor(), 0128 std::move(tls_context), std::move(logger) 0129 ) 0130 {} 0131 0132 /** 0133 * \brief Move-construct an mqtt_client from another. 0134 */ 0135 mqtt_client(mqtt_client&&) noexcept = default; 0136 0137 /** 0138 * \brief Move assignment operator. 0139 * 0140 * \details Cancels this client first. 0141 */ 0142 mqtt_client& operator=(mqtt_client&& other) noexcept { 0143 _impl->cancel(); 0144 _impl = std::move(other._impl); 0145 return *this; 0146 } 0147 0148 /** 0149 * \brief Destructor. 0150 * 0151 * \details Automatically calls \ref cancel. 0152 */ 0153 ~mqtt_client() { 0154 if (_impl) 0155 _impl->cancel(); 0156 } 0157 0158 /** 0159 * \brief Get the executor associated with the object. 0160 */ 0161 executor_type get_executor() const noexcept { 0162 return _impl->get_executor(); 0163 } 0164 0165 /** 0166 * \brief Get the context object used in TLS/SSL connection. 0167 * 0168 * \note This function may only be invoked 0169 * when the template parameter \__TlsContext\__ was configured 0170 * with non-default type during the creation of a \ref mqtt_client. 0171 * 0172 * \par Precondition 0173 * \code 0174 * !std::is_same_v<TlsContext, std::monostate> 0175 * \endcode 0176 */ 0177 template < 0178 typename Ctx = TlsContext, 0179 std::enable_if_t<!std::is_same_v<Ctx, std::monostate>, bool> = true 0180 > 0181 decltype(auto) tls_context() { 0182 return _impl->tls_context(); 0183 } 0184 0185 /** 0186 * \brief Start the Client. 0187 * 0188 * \param token Completion token that will be used to produce a 0189 * completion handler. The handler will be invoked when the operation completes. 0190 * 0191 * \par Handler signature 0192 * The handler signature for this operation: 0193 * \code 0194 * void (__ERROR_CODE__) 0195 * \endcode 0196 * 0197 * \par Completion condition 0198 * The asynchronous operation will complete with 0199 * `boost::asio::error::operation_aborted` when the client is cancelled by calling 0200 * \ref async_disconnect, \ref cancel, destruction or 0201 * if a non-recoverable error happens during a connection attempt (e.g. access denied). 0202 * 0203 * \par Error codes 0204 * The list of all possible error codes that this operation can finish with:\n 0205 * - `boost::asio::error::operation_aborted`\n 0206 * 0207 * \par Per-Operation Cancellation 0208 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0209 * - `cancellation_type::terminal` - invokes \ref cancel \n 0210 */ 0211 template < 0212 typename CompletionToken = 0213 typename asio::default_completion_token<executor_type>::type 0214 > 0215 decltype(auto) async_run(CompletionToken&& token = {}) { 0216 using Signature = void (error_code); 0217 return asio::async_initiate<CompletionToken, Signature>( 0218 detail::initiate_async_run(_impl), token 0219 ); 0220 } 0221 0222 /** 0223 * \brief Cancel all asynchronous operations. This function has terminal effects. 0224 * 0225 * \details All outstanding operations will complete 0226 * with `boost::asio::error::operation_aborted`. 0227 * 0228 * \attention This function has terminal effects and will close the Client. 0229 * The Client cannot be used before calling \ref async_run again. 0230 */ 0231 void cancel() { 0232 auto impl = _impl; 0233 _impl = impl->dup(); 0234 impl->cancel(); 0235 } 0236 0237 /** 0238 * \brief Assign a \ref will Message. 0239 * 0240 * \details The \ref will Message that the Broker should publish 0241 * after the Network Connection is closed and it is not 0242 * closed normally. 0243 * 0244 * \attention This function takes action when the client is in a non-operational state, 0245 * meaning the \ref async_run function has not been invoked. 0246 * Furthermore, you can use this function after the \ref cancel function has been called, 0247 * before the \ref async_run function is invoked again. 0248 */ 0249 mqtt_client& will(will will) { 0250 _impl->will(std::move(will)); 0251 return *this; 0252 } 0253 0254 /** 0255 * \brief Assign credentials that will be used to connect to a Broker. 0256 * 0257 * \details Credentials consist of a unique Client Identifier and, optionally, 0258 * a User Name and Password. 0259 * 0260 * \attention This function takes action when the client is in a non-operational state, 0261 * meaning the \ref async_run function has not been invoked. 0262 * Furthermore, you can use this function after the \ref cancel function has been called, 0263 * before the \ref async_run function is invoked again. 0264 */ 0265 mqtt_client& credentials( 0266 std::string client_id, 0267 std::string username = "", std::string password = "" 0268 ) { 0269 _impl->credentials( 0270 std::move(client_id), 0271 std::move(username), std::move(password) 0272 ); 0273 return *this; 0274 } 0275 0276 /** 0277 * \brief Assign a list of Brokers that the Client will attempt to connect to. 0278 * 0279 * \details The Client will cycle through the list of hosts, 0280 * attempting to establish a connection with each 0281 * until it successfully establishes a connection. 0282 * 0283 * \param hosts List of Broker addresses and ports. 0284 * Address and ports are separated with a colon `:` while 0285 * pairs of addresses and ports are separated with a comma `,`. 0286 * \param default_port The default port to connect to in case the port is not 0287 * explicitly specified in the `hosts` list. 0288 * 0289 * \attention This function takes action when the client is in a non-operational state, 0290 * meaning the \ref async_run function has not been invoked. 0291 * Furthermore, you can use this function after the \ref cancel function has been called, 0292 * before the \ref async_run function is invoked again. 0293 * 0294 * \par Example 0295 * Some valid `hosts` string: 0296 * 0297 * \code 0298 * std::string valid_hosts_1 = "broker1:1883, broker2, broker3:1883"; 0299 * std::string valid_hosts_2 = "broker1"; 0300 * \endcode 0301 * 0302 */ 0303 mqtt_client& brokers(std::string hosts, uint16_t default_port = 1883) { 0304 _impl->brokers(std::move(hosts), default_port); 0305 return *this; 0306 } 0307 0308 /** 0309 * \brief Assign an authenticator that the Client will use for 0310 * \__ENHANCED_AUTH\__ on every connect to a Broker. 0311 * Re-authentication can be initiated by calling \ref re_authenticate. 0312 * 0313 * \param authenticator Object that will be stored (move-constructed or by reference) 0314 * and used for authentication. It needs to satisfy \__Authenticator\__ concept. 0315 * 0316 * \attention This function takes action when the client is in a non-operational state, 0317 * meaning the \ref async_run function has not been invoked. 0318 * Furthermore, you can use this function after the \ref cancel function has been called, 0319 * before the \ref async_run function is invoked again. 0320 * 0321 */ 0322 template <typename Authenticator> 0323 mqtt_client& authenticator(Authenticator&& authenticator) { 0324 static_assert( 0325 detail::is_authenticator<Authenticator>, 0326 "The type does not satisfy the Authenticator concept" 0327 ); 0328 _impl->authenticator(std::forward<Authenticator>(authenticator)); 0329 return *this; 0330 } 0331 0332 /** 0333 * \brief Assign the maximum time interval that is permitted to elapse between 0334 * two transmissions from the Client. 0335 * 0336 * \details A non-zero value initiates a process of sending a \__PINGREQ\__ 0337 * packet every `seconds`. If this function is not invoked, the Client assumes 0338 * a \__KEEP_ALIVE\__ interval of 60 seconds. 0339 * 0340 * \param seconds Time interval in seconds. 0341 * 0342 * \note If the Server sends a \__SERVER_KEEP_ALIVE\__, 0343 * the Client will send a \__PINGREQ\__ packet every \__SERVER_KEEP_ALIVE\__ seconds. 0344 * 0345 * \attention This function takes action when the client is in a non-operational state, 0346 * meaning the \ref async_run function has not been invoked. 0347 * Furthermore, you can use this function after the \ref cancel function has been called, 0348 * before the \ref async_run function is invoked again. 0349 * 0350 */ 0351 mqtt_client& keep_alive(uint16_t seconds) { 0352 _impl->keep_alive(seconds); 0353 return *this; 0354 } 0355 0356 /** 0357 * \brief Assign \__CONNECT_PROPS\__ that will be sent in a \__CONNECT\__ packet. 0358 * \param props \__CONNECT_PROPS\__ sent in a \__CONNECT\__ packet. 0359 * \see See \__CONNECT_PROPS\__ for all eligible properties. 0360 */ 0361 mqtt_client& connect_properties(connect_props props) { 0362 _impl->connect_properties(std::move(props)); 0363 return *this; 0364 } 0365 0366 /** 0367 * \brief Assign a property that will be sent in a \__CONNECT\__ packet. 0368 * \param prop The \__CONNECT_PROPS\__ property to set. 0369 * \param value Value that will be assigned to the property. 0370 * 0371 * \par Example 0372 * \code 0373 * client.connect_property(prop::session_expiry_interval, 40); // ok 0374 * client.connect_property(prop::reason_string, "reason"); // does not compile, not a CONNECT prop! 0375 * \endcode 0376 * 0377 * \see See \__CONNECT_PROPS\__ for all eligible properties. 0378 */ 0379 template <prop::property_type p> 0380 mqtt_client& connect_property( 0381 std::integral_constant<prop::property_type, p> prop, 0382 prop::value_type_t<p> value 0383 ) { 0384 _impl->connect_property(prop, std::move(value)); 0385 return *this; 0386 } 0387 0388 /** 0389 * \brief Initiates \__RE_AUTHENTICATION\__ 0390 * using the authenticator given in the \ref authenticator method. 0391 * 0392 * \note If \ref authenticator was not called, this method does nothing. 0393 */ 0394 void re_authenticate() { 0395 detail::re_auth_op { _impl }.perform(); 0396 } 0397 0398 /** 0399 * \brief Retrieves the value of a specific property from the last \__CONNACK\__ packet received. 0400 * 0401 * \details The return type varies according to the property requested. 0402 * For all properties, the return type will be `std::optional` of their respective value type. 0403 * For `boost::mqtt5::prop::user_property`, the return type is 0404 * `std::vector<std::pair<std::string, std::string>>`. 0405 * 0406 * \param prop The \__CONNACK_PROPS\__ property value to retrieve. 0407 * 0408 * \par Example 0409 * \code 0410 * std::optional<std::string> auth_method = client.connack_property(boost::mqtt5::prop::authentication_method); // ok 0411 * std::optional<std::string> c_type = client.connack_property(boost::mqtt5::prop::content_type); // does not compile, not a CONNACK prop! 0412 * \endcode 0413 * 0414 * \see See \__CONNACK_PROPS\__ for all eligible properties. 0415 */ 0416 template <prop::property_type p> 0417 const auto& connack_property( 0418 std::integral_constant<prop::property_type, p> prop 0419 ) const { 0420 return _impl->connack_property(prop); 0421 } 0422 0423 /** 0424 * \brief Retrieves the \__CONNACK_PROPS\__ from the last \__CONNACK\__ packet received. 0425 * 0426 * \see See \__CONNACK_PROPS\__ for all eligible properties. 0427 */ 0428 const connack_props& connack_properties() const { 0429 return _impl->connack_properties(); 0430 } 0431 0432 /** 0433 * \brief Send a \__PUBLISH\__ packet to Broker to transport an 0434 * Application Message. 0435 * 0436 * \tparam qos_type The \ref qos_e level of assurance for delivery. 0437 * \param topic Identification of the information channel to which 0438 * Payload data is published. 0439 * \param payload The Application Message that is being published. 0440 * \param retain The \ref retain_e flag. 0441 * \param props An instance of \__PUBLISH_PROPS\__. 0442 * \param token Completion token that will be used to produce a 0443 * completion handler. The handler will be invoked when the operation completes. 0444 * On immediate completion, invocation of the handler will be performed in a manner 0445 * equivalent to using \__ASYNC_IMMEDIATE\__. 0446 * 0447 * \par Handler signature 0448 * The handler signature for this operation depends on the \ref qos_e specified:\n 0449 * 0450 * `qos` == `qos_e::at_most_once`: 0451 * \code 0452 * void ( 0453 * __ERROR_CODE__ // Result of operation 0454 * ) 0455 * \endcode 0456 * 0457 * `qos` == `qos_e::at_least_once`: 0458 * \code 0459 * void ( 0460 * __ERROR_CODE__, // Result of operation. 0461 * __REASON_CODE__, // Reason Code received from Broker. 0462 * __PUBACK_PROPS__ // Properties received in the PUBACK packet. 0463 * ) 0464 * \endcode 0465 * 0466 * `qos` == `qos_e::exactly_once`: 0467 * \code 0468 * void ( 0469 * __ERROR_CODE__, // Result of operation. 0470 * __REASON_CODE__, // Reason Code received from Broker. 0471 * __PUBCOMP_PROPS__ // Properties received in the PUBCOMP packet. 0472 * ) 0473 * \endcode 0474 * 0475 * \par Completion condition 0476 * Depending on the \ref qos_e specified, the asynchronous operation will complete 0477 * when one of the following conditions is true:\n 0478 * - If `qos` == `qos_e::at_most_once` and the Client 0479 * has successfully written the packet to the transport. \n 0480 * - If `qos` == `qos_e::at_least_once` and the packet has 0481 * been sent and acknowledged through the reception of a \__PUBACK\__ packet. 0482 * - If `qos` == `qos_e::exactly_once` and the packet has 0483 * been sent and fully acknowledged through the reception of a \__PUBCOMP\__ packet. 0484 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0485 * 0486 * \par Error codes 0487 * The list of all possible error codes that this operation can finish with:\n 0488 * - `boost::system::errc::errc_t::success` \n 0489 * - `boost::asio::error::operation_aborted` \n 0490 * - `boost::asio::error::no_recovery` \n 0491 * - \ref boost::mqtt5::client::error::malformed_packet 0492 * - \ref boost::mqtt5::client::error::packet_too_large 0493 * - \ref boost::mqtt5::client::error::pid_overrun 0494 * - \ref boost::mqtt5::client::error::qos_not_supported 0495 * - \ref boost::mqtt5::client::error::retain_not_available 0496 * - \ref boost::mqtt5::client::error::topic_alias_maximum_reached 0497 * - \ref boost::mqtt5::client::error::invalid_topic 0498 * 0499 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0500 * 0501 * \par Per-Operation Cancellation 0502 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0503 * - `cancellation_type::terminal` - invokes \ref cancel \n 0504 * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__PUBLISH\__ packet \n 0505 * 0506 */ 0507 template <qos_e qos_type, 0508 typename CompletionToken = 0509 typename asio::default_completion_token<executor_type>::type 0510 > 0511 decltype(auto) async_publish( 0512 std::string topic, std::string payload, 0513 retain_e retain, const publish_props& props, 0514 CompletionToken&& token = {} 0515 ) { 0516 using Signature = detail::on_publish_signature<qos_type>; 0517 return asio::async_initiate<CompletionToken, Signature>( 0518 detail::initiate_async_publish<client_service_type, qos_type>(_impl), 0519 token, 0520 std::move(topic), std::move(payload), retain, props 0521 ); 0522 } 0523 0524 /** 0525 * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a Subscription 0526 * to one or more Topics of interest. 0527 * 0528 * \details After the Subscription has been established, the Broker will send 0529 * PUBLISH packets to the Client to forward Application Messages that were published 0530 * to Topics that the Client subscribed to. The Application Messages can be received 0531 * with \ref mqtt_client::async_receive function. 0532 * 0533 * \param topics A list of \ref subscribe_topic of interest. 0534 * \param props An instance of \__SUBSCRIBE_PROPS\__. 0535 * \param token Completion token that will be used to produce a 0536 * completion handler. The handler will be invoked when the operation completes. 0537 * On immediate completion, invocation of the handler will be performed in a manner 0538 * equivalent to using \__ASYNC_IMMEDIATE\__. 0539 * 0540 * \par Handler signature 0541 * The handler signature for this operation: 0542 * \code 0543 * void ( 0544 * __ERROR_CODE__, // Result of operation. 0545 * std::vector<__REASON_CODE__>, // Vector of Reason Codes indicating 0546 * // the Subscription result for each Topic 0547 * // in the SUBSCRIBE packet. 0548 * __SUBACK_PROPS__, // Properties received in the SUBACK packet. 0549 * ) 0550 * \endcode 0551 * 0552 * \par Completion condition 0553 * The asynchronous operation will complete when one of the following conditions is true:\n 0554 * - The Client has successfully sent a \__SUBSCRIBE\__ packet 0555 * and has received a \__SUBACK\__ response from the Broker.\n 0556 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0557 * 0558 * \par Error codes 0559 * The list of all possible error codes that this operation can finish with:\n 0560 * - `boost::system::errc::errc_t::success` \n 0561 * - `boost::asio::error::no_recovery` \n 0562 * - `boost::asio::error::operation_aborted` \n 0563 * - \ref boost::mqtt5::client::error::malformed_packet 0564 * - \ref boost::mqtt5::client::error::packet_too_large 0565 * - \ref boost::mqtt5::client::error::pid_overrun 0566 * - \ref boost::mqtt5::client::error::invalid_topic 0567 * - \ref boost::mqtt5::client::error::wildcard_subscription_not_available 0568 * - \ref boost::mqtt5::client::error::subscription_identifier_not_available 0569 * - \ref boost::mqtt5::client::error::shared_subscription_not_available 0570 * 0571 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0572 * 0573 * \par Per-Operation Cancellation 0574 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0575 * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n 0576 * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__SUBSCRIBE\__ packet \n 0577 * 0578 */ 0579 template < 0580 typename CompletionToken = 0581 typename asio::default_completion_token<executor_type>::type 0582 > 0583 decltype(auto) async_subscribe( 0584 const std::vector<subscribe_topic>& topics, 0585 const subscribe_props& props, 0586 CompletionToken&& token = {} 0587 ) { 0588 using Signature = void ( 0589 error_code, std::vector<reason_code>, suback_props 0590 ); 0591 return asio::async_initiate<CompletionToken, Signature>( 0592 detail::initiate_async_subscribe(_impl), token, 0593 topics, props 0594 ); 0595 } 0596 0597 /** 0598 * \brief Send a \__SUBSCRIBE\__ packet to Broker to create a Subscription 0599 * to one Topic of interest. 0600 * 0601 * \details After the Subscription has been established, the Broker will send 0602 * \__PUBLISH\__ packets to the Client to forward Application Messages that were published 0603 * to Topics that the Client subscribed to. The Application Messages can be received 0604 * with \ref mqtt_client::async_receive function. 0605 * 0606 * \param topic A \ref subscribe_topic of interest. 0607 * \param props An instance of \__SUBSCRIBE_PROPS\__. 0608 * \param token Completion token that will be used to produce a 0609 * completion handler. The handler will be invoked when the operation completes. 0610 * On immediate completion, invocation of the handler will be performed in a manner 0611 * equivalent to using \__ASYNC_IMMEDIATE\__. 0612 * 0613 * \par Handler signature 0614 * The handler signature for this operation: 0615 * \code 0616 * void ( 0617 * __ERROR_CODE__, // Result of operation. 0618 * std::vector<__REASON_CODE__>, // Vector of Reason Codes containing the 0619 * // single Subscription result for the Topic 0620 * // in the SUBSCRIBE packet. 0621 * __SUBACK_PROPS__, // Properties received in the SUBACK packet. 0622 * ) 0623 * \endcode 0624 * 0625 * \par Completion condition 0626 * The asynchronous operation will complete when one of the following conditions is true:\n 0627 * - The Client has successfully sent a \__SUBSCRIBE\__ packet 0628 * and has received a \__SUBACK\__ response from the Broker.\n 0629 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0630 * 0631 * \par Error codes 0632 * The list of all possible error codes that this operation can finish with:\n 0633 * - `boost::system::errc::errc_t::success` \n 0634 * - `boost::asio::error::no_recovery` \n 0635 * - `boost::asio::error::operation_aborted` \n 0636 * - \ref boost::mqtt5::client::error::malformed_packet 0637 * - \ref boost::mqtt5::client::error::packet_too_large 0638 * - \ref boost::mqtt5::client::error::pid_overrun 0639 * - \ref boost::mqtt5::client::error::invalid_topic 0640 * - \ref boost::mqtt5::client::error::wildcard_subscription_not_available 0641 * - \ref boost::mqtt5::client::error::subscription_identifier_not_available 0642 * - \ref boost::mqtt5::client::error::shared_subscription_not_available 0643 * 0644 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0645 * 0646 * \par Per-Operation Cancellation 0647 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0648 * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n 0649 * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__SUBSCRIBE\__ packet \n 0650 * 0651 */ 0652 template < 0653 typename CompletionToken = 0654 typename asio::default_completion_token<executor_type>::type 0655 > 0656 decltype(auto) async_subscribe( 0657 const subscribe_topic& topic, const subscribe_props& props, 0658 CompletionToken&& token = {} 0659 ) { 0660 return async_subscribe( 0661 std::vector<subscribe_topic> { topic }, props, 0662 std::forward<CompletionToken>(token) 0663 ); 0664 } 0665 0666 0667 /** 0668 * \brief Send an \__UNSUBSCRIBE\__ packet to Broker to unsubscribe from one 0669 * or more Topics. 0670 * 0671 * \note The Client may still receive residual Application Messages 0672 * through the \ref mqtt_client::async_receive function 0673 * from Topics the Client just unsubscribed to. 0674 * 0675 * \param topics List of Topics to unsubscribe from. 0676 * \param props An instance of \__UNSUBSCRIBE_PROPS\__. 0677 * \param token Completion token that will be used to produce a 0678 * completion handler. The handler will be invoked when the operation completes. 0679 * On immediate completion, invocation of the handler will be performed in a manner 0680 * equivalent to using \__ASYNC_IMMEDIATE\__. 0681 * 0682 * \par Handler signature 0683 * The handler signature for this operation: 0684 * \code 0685 * void ( 0686 * __ERROR_CODE__, // Result of operation. 0687 * std::vector<__REASON_CODE__>, // Vector of Reason Codes indicating 0688 * // the result of unsubscribe operation 0689 * // for each Topic in the UNSUBSCRIBE packet. 0690 * __UNSUBACK_PROPS__, // Properties received in the UNSUBACK packet. 0691 * ) 0692 * \endcode 0693 * 0694 * \par Completion condition 0695 * The asynchronous operation will complete when one of the following conditions is true:\n 0696 * - The Client has successfully sent an \__UNSUBSCRIBE\__ packet 0697 * and has received an \__UNSUBACK\__ response from the Broker.\n 0698 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0699 * 0700 * \par Error codes 0701 * The list of all possible error codes that this operation can finish with:\n 0702 * - `boost::system::errc::errc_t::success` \n 0703 * - `boost::asio::error::no_recovery` \n 0704 * - `boost::asio::error::operation_aborted` \n 0705 * - \ref boost::mqtt5::client::error::malformed_packet 0706 * - \ref boost::mqtt5::client::error::packet_too_large 0707 * - \ref boost::mqtt5::client::error::pid_overrun 0708 * - \ref boost::mqtt5::client::error::invalid_topic 0709 * 0710 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0711 * 0712 * \par Per-Operation Cancellation 0713 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0714 * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n 0715 * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__UNSUBSCRIBE\__ packet \n 0716 * 0717 */ 0718 template < 0719 typename CompletionToken = 0720 typename asio::default_completion_token<executor_type>::type 0721 > 0722 decltype(auto) async_unsubscribe( 0723 const std::vector<std::string>& topics, const unsubscribe_props& props, 0724 CompletionToken&& token = {} 0725 ) { 0726 using Signature = void ( 0727 error_code, std::vector<reason_code>, unsuback_props 0728 ); 0729 return asio::async_initiate<CompletionToken, Signature>( 0730 detail::initiate_async_unsubscribe(_impl), token, 0731 topics, props 0732 ); 0733 } 0734 0735 /** 0736 * \brief Send an \__UNSUBSCRIBE\__ packet to Broker to unsubscribe 0737 * from one Topic. 0738 * 0739 * \note The Client may still receive residual Application Messages 0740 * through the \ref mqtt_client::async_receive function 0741 * from Topics the Client just unsubscribed to. 0742 * 0743 * \param topic Topic to unsubscribe from. 0744 * \param props An instance of \__UNSUBSCRIBE_PROPS\__. 0745 * \param token Completion token that will be used to produce a 0746 * completion handler. The handler will be invoked when the operation completes. 0747 * On immediate completion, invocation of the handler will be performed in a manner 0748 * equivalent to using \__ASYNC_IMMEDIATE\__. 0749 * 0750 * \par Handler signature 0751 * The handler signature for this operation: 0752 * \code 0753 * void ( 0754 * __ERROR_CODE__, // Result of operation. 0755 * std::vector<__REASON_CODE__>, // Vector of Reason Codes containing 0756 * // the result of unsubscribe operation 0757 * // for the Topic in the UNSUBSCRIBE packet. 0758 * __UNSUBACK_PROPS__, // Properties received in the UNSUBACK packet. 0759 * ) 0760 * \endcode 0761 * 0762 * \par Completion condition 0763 * The asynchronous operation will complete when one of the following conditions is true:\n 0764 * - The Client has successfully sent an \__UNSUBSCRIBE\__ packet 0765 * and has received an \__UNSUBACK\__ response from the Broker.\n 0766 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0767 * 0768 * \par Error codes 0769 * The list of all possible error codes that this operation can finish with:\n 0770 * - `boost::system::errc::errc_t::success` \n 0771 * - `boost::asio::error::no_recovery` \n 0772 * - `boost::asio::error::operation_aborted` \n 0773 * - \ref boost::mqtt5::client::error::malformed_packet 0774 * - \ref boost::mqtt5::client::error::packet_too_large 0775 * - \ref boost::mqtt5::client::error::pid_overrun 0776 * - \ref boost::mqtt5::client::error::invalid_topic 0777 * 0778 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0779 * 0780 * \par Per-Operation Cancellation 0781 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0782 * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n 0783 * - `cancellation_type::partial` & `cancellation_type::total` - prevents potential resending of the \__UNSUBSCRIBE\__ packet \n 0784 * 0785 */ 0786 template < 0787 typename CompletionToken = 0788 typename asio::default_completion_token<executor_type>::type 0789 > 0790 decltype(auto) async_unsubscribe( 0791 const std::string& topic, const unsubscribe_props& props, 0792 CompletionToken&& token = {} 0793 ) { 0794 return async_unsubscribe( 0795 std::vector<std::string> { topic }, props, 0796 std::forward<CompletionToken>(token) 0797 ); 0798 } 0799 0800 0801 /** 0802 * \brief Asynchronously receive an Application Message. 0803 * 0804 * \details The Client will receive and complete deliveries for all the 0805 * \__PUBLISH\__ packets received from the Broker throughout its lifetime. 0806 * The Client will store them internally in the order they were delivered. 0807 * Calling this function will attempt to receive an Application Message 0808 * from internal storage. 0809 * 0810 * \note It is only recommended to call this function if you have established 0811 * a successful Subscription to a Topic using the \ref async_subscribe function. 0812 * 0813 * \param token Completion token that will be used to produce a 0814 * completion handler. The handler will be invoked when the operation completes. 0815 * On immediate completion, invocation of the handler will be performed in a manner 0816 * equivalent to using \__POST\__. 0817 * 0818 * \par Handler signature 0819 * The handler signature for this operation: 0820 * \code 0821 * void ( 0822 * __ERROR_CODE__, // Result of operation. 0823 * std::string, // Topic, the origin of the Application Message. 0824 * std::string, // Payload, the content of the Application Message. 0825 * __PUBLISH_PROPS__, // Properties received in the PUBLISH packet. 0826 * ) 0827 * \endcode 0828 * 0829 * \par Completion condition 0830 * The asynchronous operation will complete when one of the following conditions is true:\n 0831 * - The Client has a pending Application Message in its internal storage 0832 * ready to be received. 0833 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0834 * 0835 * \par Error codes 0836 * The list of all possible error codes that this operation can finish with:\n 0837 * - `boost::system::errc::errc_t::success`\n 0838 * - `boost::asio::error::operation_aborted`\n 0839 * - \ref boost::mqtt5::client::error::session_expired 0840 * 0841 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0842 * 0843 * \par Per-Operation Cancellation 0844 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0845 * - `cancellation_type::terminal` \n 0846 * - `cancellation_type::partial` \n 0847 * - `cancellation_type::total` \n 0848 */ 0849 template < 0850 typename CompletionToken = 0851 typename asio::default_completion_token<executor_type>::type 0852 > 0853 decltype(auto) async_receive(CompletionToken&& token = {}) { 0854 return _impl->async_channel_receive(std::forward<CompletionToken>(token)); 0855 } 0856 0857 /** 0858 * \brief Disconnect the Client by sending a \__DISCONNECT\__ packet 0859 * with a specified Reason Code. This function has terminal effects. 0860 * 0861 * \details The Client will attempt to send a \__DISCONNECT\__ packet to the Broker 0862 * with a Reason Code describing the reason for disconnection. 0863 * If the \__DISCONNECT\__ packet is successfully transmitted, 0864 * or if `5 seconds` elapsed without a successful send, the Client will terminate the connection. 0865 * 0866 * \attention This function has terminal effects and will close the Client. 0867 * See \ref mqtt_client::cancel. 0868 * 0869 * \param reason_code Reason Code to notify 0870 * the Broker of the reason for the disconnection. 0871 * \param props An instance of \__DISCONNECT_PROPS\__. 0872 * \param token Completion token that will be used to produce a 0873 * completion handler. The handler will be invoked when the operation completes. 0874 * 0875 * \par Handler signature 0876 * The handler signature for this operation: 0877 * \code 0878 * void ( 0879 * __ERROR_CODE__ // Result of operation. 0880 * ) 0881 * \endcode 0882 * 0883 * \par Completion condition 0884 * The asynchronous operation will complete when one of the following conditions is true:\n 0885 * - The Client has sent a \__DISCONNECT\__ packet.\n 0886 * - 5 seconds have elapsed without a successful send.\n 0887 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0888 * 0889 * \par Error codes 0890 * The list of all possible error codes that this operation can finish with:\n 0891 * - `boost::system::errc::errc_t::success`\n 0892 * - `boost::asio::error::operation_aborted`[footnote 0893 This error code can appear if the Client fails to send the \__DISCONNECT\__ packet to the Server. 0894 Regardless, the connection to the Server is terminated, and the Client is cancelled. 0895 ]\n 0896 * - \ref boost::mqtt5::client::error::malformed_packet 0897 * 0898 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0899 * 0900 * \par Per-Operation Cancellation 0901 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0902 * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n 0903 * 0904 */ 0905 template < 0906 typename CompletionToken = 0907 typename asio::default_completion_token<executor_type>::type 0908 > 0909 decltype(auto) async_disconnect( 0910 disconnect_rc_e reason_code, const disconnect_props& props, 0911 CompletionToken&& token = {} 0912 ) { 0913 auto impl = _impl; 0914 _impl = impl->dup(); 0915 return detail::async_terminal_disconnect( 0916 detail::disconnect_rc_e(static_cast<uint8_t>(reason_code)), 0917 props, impl, std::forward<CompletionToken>(token) 0918 ); 0919 } 0920 0921 /** 0922 * \brief Disconnect the Client by sending a \__DISCONNECT\__ packet 0923 * with a Reason Code of reason_codes.normal_disconnection. 0924 * This function has terminal effects. 0925 * 0926 * \details The Client will attempt to send a \__DISCONNECT\__ packet to the Broker 0927 * with a Reason Code describing the reason for disconnection. 0928 * If the \__DISCONNECT\__ packet is successfully transmitted, 0929 * or if `5 seconds` elapsed without a successful send, the Client will terminate the connection. 0930 * 0931 * \attention This function has terminal effects and will close the Client. 0932 * See \ref mqtt_client::cancel. 0933 * 0934 * \param token Completion token that will be used to produce a 0935 * completion handler. The handler will be invoked when the operation completes. 0936 * 0937 * \par Handler signature 0938 * The handler signature for this operation: 0939 * \code 0940 * void ( 0941 * __ERROR_CODE__ // Result of operation. 0942 * ) 0943 * \endcode 0944 * 0945 * \par Completion condition 0946 * The asynchronous operation will complete when one of the following conditions is true:\n 0947 * - The Client has attempted to send a \__DISCONNECT\__ packet, regardless of whether 0948 * the sending was successful or not.\n 0949 * - An error occurred. This is indicated by an associated \__ERROR_CODE\__ in the handler.\n 0950 * 0951 * \par Error codes 0952 * The list of all possible error codes that this operation can finish with:\n 0953 * - `boost::system::errc::errc_t::success`\n 0954 * - `boost::asio::error::operation_aborted`[footnote 0955 This error code can appear if the Client fails to send the \__DISCONNECT\__ packet to the Server. 0956 Regardless, the connection to the Server is terminated, and the Client is cancelled. 0957 ]\n 0958 * - \ref boost::mqtt5::client::error::malformed_packet 0959 * 0960 * Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code. 0961 * 0962 * \par Per-Operation Cancellation 0963 * This asynchronous operation supports cancellation for the following \__CANCELLATION_TYPE\__ values:\n 0964 * - `cancellation_type::terminal` - invokes \ref mqtt_client::cancel \n 0965 */ 0966 template < 0967 typename CompletionToken = 0968 typename asio::default_completion_token<executor_type>::type 0969 > 0970 decltype(auto) async_disconnect(CompletionToken&& token = {}) { 0971 return async_disconnect( 0972 disconnect_rc_e::normal_disconnection, 0973 disconnect_props {}, std::forward<CompletionToken>(token) 0974 ); 0975 } 0976 0977 }; 0978 0979 } // end namespace boost::mqtt5 0980 0981 #endif // !BOOST_MQTT5_MQTT_CLIENT_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |