diff --git a/src/connect_options.cpp b/src/connect_options.cpp index e569358..8c922d1 100644 --- a/src/connect_options.cpp +++ b/src/connect_options.cpp @@ -31,6 +31,12 @@ const MQTTAsync_connectOptions connect_options::DFLT_C_STRUCT = const MQTTAsync_connectOptions connect_options::DFLT_C_STRUCT5 = MQTTAsync_connectOptions_initializer5; +const MQTTAsync_connectOptions connect_options::DFLT_C_STRUCT_WS = + MQTTAsync_connectOptions_initializer_ws; + +const MQTTAsync_connectOptions connect_options::DFLT_C_STRUCT5_WS = + MQTTAsync_connectOptions_initializer5_ws; + connect_options::connect_options(int ver /*=MQTTVERSION_DEFAULT*/) { opts_ = (ver < MQTTVERSION_5) ? DFLT_C_STRUCT : DFLT_C_STRUCT5; diff --git a/src/mqtt/connect_options.h b/src/mqtt/connect_options.h index f674dda..e3e8f31 100644 --- a/src/mqtt/connect_options.h +++ b/src/mqtt/connect_options.h @@ -46,12 +46,18 @@ namespace mqtt { */ class connect_options { - /** The default C struct */ + /** The default C struct for non-WebSocket connections */ static const MQTTAsync_connectOptions DFLT_C_STRUCT; - /** The default C struct for MQTT v5 */ + /** The default C struct for non-Websocket MQTT v5 connections */ static const MQTTAsync_connectOptions DFLT_C_STRUCT5; + /** The default C struct for WebSocket connections */ + static const MQTTAsync_connectOptions DFLT_C_STRUCT_WS; + + /** The default C struct for Websocket MQTT v5 connections */ + static const MQTTAsync_connectOptions DFLT_C_STRUCT5_WS; + /** The underlying C connection options */ MQTTAsync_connectOptions opts_; @@ -109,6 +115,12 @@ class connect_options */ void update_c_struct(); + /** + * Creates the options from a C option struct. + * @param copts The C options struct. + */ + connect_options(const MQTTAsync_connectOptions& copts) : opts_(copts) {} + public: /** Smart/shared pointer to an object of this class. */ using ptr_t = std::shared_ptr; @@ -141,6 +153,42 @@ public: * @param opt Another object to move into this new one. */ connect_options(connect_options&& opt); + /** + * Creates default options for an MQTT v3.x connection. + * @return Default options for an MQTT v3.x connection. + */ + static connect_options v3() { + return connect_options(DFLT_C_STRUCT); + } + /** + * Creates default options for an MQTT v5 connection. + * @return Default options for an MQTT v5 connection. + */ + static connect_options v5() { + return connect_options(DFLT_C_STRUCT5); + } + /** + * Creates default options for an MQTT v3.x connection using WebSockets. + * + * The keepalive interval is set to 45 seconds to avoid webserver 60 + * second inactivity timeouts. + * + * @return Default options for an MQTT v3.x connection using websockets. + */ + static connect_options ws() { + return connect_options(DFLT_C_STRUCT_WS); + } + /** + * Creates default options for an MQTT v5 connection using WebSockets. + * + * The keepalive interval is set to 45 seconds to avoid webserver 60 + * second inactivity timeouts. + * + * @return Default options for an MQTT v5 connection using websockets. + */ + static connect_options v5_ws() { + return connect_options(DFLT_C_STRUCT5_WS); + } /** * Copy assignment. * @param opt Another object to copy. @@ -628,6 +676,54 @@ public: * Default constructor. */ explicit connect_options_builder(int ver=MQTTVERSION_DEFAULT) : opts_(ver) {} + /** + * Copy constructor from an existing set of options. + */ + explicit connect_options_builder(const connect_options& opts) : opts_(opts) {} + /** + * Move constructor from an existing set of options. + */ + explicit connect_options_builder(const connect_options&& opts) : opts_(std::move(opts)) {} + /** + * Creates the default options builder for an MQTT v3.x connection. + * @return An options builder for an MQTT v3.x connection. + */ + static connect_options_builder v3() { + return connect_options_builder{ connect_options::v3() }; + } + /** + * Creates the default options builder for an MQTT v5 connection. + * @return An options builder for an MQTT v5 connection. + */ + static connect_options_builder v5() { + return connect_options_builder{ connect_options::v5() }; + } + /** + * Creates the default options builder for an MQTT v3.x connection using + * WebSockets. + * + * The keepalive interval is set to 45 seconds to avoid webserver 60 + * second inactivity timeouts. + * + * @return An options builder for an MQTT v3.x connection using + * websockets. + */ + static connect_options_builder ws() { + return connect_options_builder{ connect_options::ws() }; + } + /** + * Creates the default options for an MQTT v5 connection using + * WebSockets + * . + * The keepalive interval is set to 45 seconds to avoid webserver 60 + * second inactivity timeouts. + * + * @return An options builder for an MQTT v5 connection using + * websockets. + */ + static connect_options_builder v5_ws() { + return connect_options_builder{ connect_options::v5_ws() }; + } /** * Sets whether the server should remember state for the client across * reconnects. (MQTT v3.x only) diff --git a/test/unit/test_connect_options.cpp b/test/unit/test_connect_options.cpp index 4ae1b00..de053a9 100644 --- a/test/unit/test_connect_options.cpp +++ b/test/unit/test_connect_options.cpp @@ -35,6 +35,7 @@ static const size_t CSIG_LEN = std::strlen(CSIG); // These must match the C init struct static const int DFLT_KEEP_ALIVE = 60; +static const int DFLT_WS_KEEP_ALIVE = 45; static const int DFLT_CONNECT_TIMEOUT = 30; static const bool DFLT_AUTO_RECONNECT = false; @@ -44,9 +45,9 @@ static const std::string PASSWD { "xyzpdq" }; static const std::string EMPTY_STR; static const std::vector URIsVec = { - "tcp://server1:1883", - "tcp://server2:1883", - "ssl://server3:8883" + "mqtt://server1:1883", + "mqtt://server2:1883", + "mqtts://server3:8883" }; const const_string_collection_ptr URIs = std::make_shared(URIsVec); @@ -55,7 +56,6 @@ static constexpr token::Type TOKEN_TYPE = token::Type::CONNECT; static const std::string HTTP_PROXY { "http://localhost:80" }; static const std::string HTTPS_PROXY { "https://localhost:443" }; - // ---------------------------------------------------------------------- // Test the default constructor // ---------------------------------------------------------------------- @@ -503,3 +503,47 @@ TEST_CASE("set_token", "[options]") } } +// ---------------------------------------------------------------------- +// Test the builder constructors +// ---------------------------------------------------------------------- + +TEST_CASE("connect_options_builder default generator", "[options]") +{ + mqtt::connect_options opts; + + // Default is v3.x + + opts = mqtt::connect_options_builder().finalize(); + + REQUIRE(MQTTVERSION_DEFAULT == opts.get_mqtt_version()); + REQUIRE(DFLT_KEEP_ALIVE == (int) opts.get_keep_alive_interval().count()); + + // Explicit v3 + + opts = mqtt::connect_options_builder::v3().finalize(); + + REQUIRE(MQTTVERSION_DEFAULT == opts.get_mqtt_version()); + REQUIRE(DFLT_KEEP_ALIVE == (int) opts.get_keep_alive_interval().count()); + + // v5 + + opts = mqtt::connect_options_builder::v5().finalize(); + + REQUIRE(MQTTVERSION_5 == opts.get_mqtt_version()); + REQUIRE(DFLT_KEEP_ALIVE == (int) opts.get_keep_alive_interval().count()); + + // WebSocket + + opts = mqtt::connect_options_builder::ws().finalize(); + + REQUIRE(MQTTVERSION_DEFAULT == opts.get_mqtt_version()); + REQUIRE(DFLT_WS_KEEP_ALIVE == (int) opts.get_keep_alive_interval().count()); + + // Explicit WebSocket v5 + + opts = mqtt::connect_options_builder::v5_ws().finalize(); + + REQUIRE(MQTTVERSION_5 == opts.get_mqtt_version()); + REQUIRE(DFLT_WS_KEEP_ALIVE == (int) opts.get_keep_alive_interval().count()); +} +