Commit 2569446f0a0768735feea538f102642d27c69424
1 parent
8f48be6b
Added extra subscription checks to prevent double connections
Showing
9 changed files
with
202 additions
and
27 deletions
CMakeLists.txt
| @@ -11,6 +11,7 @@ add_subdirectory(src) | @@ -11,6 +11,7 @@ add_subdirectory(src) | ||
| 11 | add_subdirectory(examples/connect) | 11 | add_subdirectory(examples/connect) |
| 12 | add_subdirectory(examples/pub) | 12 | add_subdirectory(examples/pub) |
| 13 | add_subdirectory(examples/sub) | 13 | add_subdirectory(examples/sub) |
| 14 | +add_subdirectory(examples/subunsub) | ||
| 14 | 15 | ||
| 15 | include(packaging) | 16 | include(packaging) |
| 16 | package_component() | 17 | package_component() |
examples/sub/main.cpp
| @@ -27,6 +27,8 @@ | @@ -27,6 +27,8 @@ | ||
| 27 | 27 | ||
| 28 | #include "subscriber.h" | 28 | #include "subscriber.h" |
| 29 | 29 | ||
| 30 | +const int MAX_LOOP_COUNT = 10; | ||
| 31 | + | ||
| 30 | enum TIME_RES | 32 | enum TIME_RES |
| 31 | { | 33 | { |
| 32 | T_MICRO, | 34 | T_MICRO, |
| @@ -65,6 +67,7 @@ void sleepcp( int number, TIME_RES resolution = T_MILLI ) // Cross-platform s | @@ -65,6 +67,7 @@ void sleepcp( int number, TIME_RES resolution = T_MILLI ) // Cross-platform s | ||
| 65 | 67 | ||
| 66 | int main( int argc, char* argv[] ) | 68 | int main( int argc, char* argv[] ) |
| 67 | { | 69 | { |
| 70 | + int loop_counter = 0; | ||
| 68 | // Satisfy the compiler | 71 | // Satisfy the compiler |
| 69 | (void)argc; | 72 | (void)argc; |
| 70 | (void)argv; | 73 | (void)argv; |
| @@ -79,14 +82,32 @@ int main( int argc, char* argv[] ) | @@ -79,14 +82,32 @@ int main( int argc, char* argv[] ) | ||
| 79 | pSubscriber->connect( "localhost", 1883, "", "", "test/subscriber/LWT", "Subscriber disconnected." ); | 82 | pSubscriber->connect( "localhost", 1883, "", "", "test/subscriber/LWT", "Subscriber disconnected." ); |
| 80 | 83 | ||
| 81 | std::cout << "Subscribing to the test-topic....." << std::endl; | 84 | std::cout << "Subscribing to the test-topic....." << std::endl; |
| 82 | - pSubscriber->subscribe( "test/publisher/#" ); | 85 | + pSubscriber->subscribe( "test/publisher/TestPublisher_0" ); |
| 86 | + pSubscriber->subscribe( "test/publisher/TestPublisher_1" ); | ||
| 87 | + pSubscriber->subscribe( "test/publisher/TestPublisher_2" ); | ||
| 88 | + pSubscriber->subscribe( "test/publisher/TestPublisher_3" ); | ||
| 83 | 89 | ||
| 84 | // Start a loop to give the subscriber the possibility to do its work. | 90 | // Start a loop to give the subscriber the possibility to do its work. |
| 85 | - while( 1 ) | 91 | + while (loop_counter < MAX_LOOP_COUNT) |
| 86 | { | 92 | { |
| 87 | sleepcp( 1, T_SECONDS ); // Sleep 1 Sec to give the scheduler the change to interfene. | 93 | sleepcp( 1, T_SECONDS ); // Sleep 1 Sec to give the scheduler the change to interfene. |
| 88 | std::cout << "."; | 94 | std::cout << "."; |
| 95 | + loop_counter++; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + std::cout << "Unsubscribing from test/publisher/#" << std::endl; | ||
| 99 | + | ||
| 100 | + pSubscriber->unsubscribe("test/publisher/#" ); | ||
| 101 | + pSubscriber->unsubscribe( "test/publisher/TestPublisher_0" ); | ||
| 102 | + pSubscriber->unsubscribe( "test/publisher/TestPublisher_1" ); | ||
| 103 | + pSubscriber->unsubscribe( "test/publisher/TestPublisher_2" ); | ||
| 104 | + | ||
| 105 | + while (1) | ||
| 106 | + { | ||
| 107 | + sleepcp(1, T_MILLI); // Sleep 1 Sec to give the scheduler the change to interfene. | ||
| 108 | + std::cout << "."; | ||
| 89 | } | 109 | } |
| 110 | + | ||
| 90 | } | 111 | } |
| 91 | else | 112 | else |
| 92 | { | 113 | { |
examples/sub/subscriber.cpp
| @@ -43,6 +43,11 @@ void Subscriber::subscribe( const std::string &message_topic ) | @@ -43,6 +43,11 @@ void Subscriber::subscribe( const std::string &message_topic ) | ||
| 43 | }); | 43 | }); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | +void Subscriber::unsubscribe( const std::string &message_topic ) | ||
| 47 | +{ | ||
| 48 | + m_mqtt_client.unsubscribe( message_topic, 1 ); | ||
| 49 | +} | ||
| 50 | + | ||
| 46 | void Subscriber::receive_data( const std::string &message_topic, const std::string &message_payload ) | 51 | void Subscriber::receive_data( const std::string &message_topic, const std::string &message_payload ) |
| 47 | { | 52 | { |
| 48 | std::cout << "[Subscriber::receive_data] - Received message : " << message_payload << " from topic : " << message_topic << std::endl; | 53 | std::cout << "[Subscriber::receive_data] - Received message : " << message_payload << " from topic : " << message_topic << std::endl; |
examples/sub/subscriber.h
| @@ -41,6 +41,8 @@ public: | @@ -41,6 +41,8 @@ public: | ||
| 41 | 41 | ||
| 42 | void subscribe( const std::string &message_topic ); | 42 | void subscribe( const std::string &message_topic ); |
| 43 | 43 | ||
| 44 | + void unsubscribe( const std::string &message_topic ); | ||
| 45 | + | ||
| 44 | protected: | 46 | protected: |
| 45 | void receive_data( const std::string &message_topic, const std::string &message_payload ); | 47 | void receive_data( const std::string &message_topic, const std::string &message_payload ); |
| 46 | 48 |
examples/subunsub/CMakeLists.txt
0 โ 100644
| 1 | +cmake_minimum_required(VERSION 3.0) | ||
| 2 | +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake) | ||
| 3 | + | ||
| 4 | +include(projectheader) | ||
| 5 | +project_header(test_subunsub) | ||
| 6 | + | ||
| 7 | +include_directories( SYSTEM | ||
| 8 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../include | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +include(compiler) | ||
| 12 | +set(SRC_LIST | ||
| 13 | + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp | ||
| 14 | +) | ||
| 15 | + | ||
| 16 | +add_executable( ${PROJECT_NAME} | ||
| 17 | + ${SRC_LIST} | ||
| 18 | +) | ||
| 19 | + | ||
| 20 | +target_link_libraries( | ||
| 21 | + ${PROJECT_NAME} | ||
| 22 | + mqtt-cpp | ||
| 23 | +) | ||
| 24 | + | ||
| 25 | +set_target_properties( ${PROJECT_NAME} PROPERTIES | ||
| 26 | + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin | ||
| 27 | + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib | ||
| 28 | + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib | ||
| 29 | +) | ||
| 30 | + | ||
| 31 | +include(installation) | ||
| 32 | +install_application() |
examples/subunsub/main.cpp
0 โ 100644
| 1 | +#include <iostream> | ||
| 2 | +#include <string> | ||
| 3 | +#include <vector> | ||
| 4 | + | ||
| 5 | +#include "mqttclient.h" | ||
| 6 | + | ||
| 7 | +using namespace osdev::components::mqtt; | ||
| 8 | + | ||
| 9 | +std::vector<std::string> vecTopics = | ||
| 10 | +{ | ||
| 11 | + "test/publisher/TestPublisher_0", | ||
| 12 | + "test/publisher/TestPublisher_1", | ||
| 13 | + "test/publisher/TestPublisher_2", | ||
| 14 | + "test/publisher/TestPublisher_3", | ||
| 15 | + "test/publisher/TestPublisher_4", | ||
| 16 | + "test/publisher/TestPublisher_5", | ||
| 17 | + "test/publisher/TestPublisher_6", | ||
| 18 | + "test/publisher/TestPublisher_7", | ||
| 19 | + "test/publisher/TestPublisher_8", | ||
| 20 | + "test/publisher/TestPublisher_9", | ||
| 21 | +}; | ||
| 22 | + | ||
| 23 | +MqttClient oClient("SubscriptionTest"); | ||
| 24 | + | ||
| 25 | +enum TIME_RES | ||
| 26 | +{ | ||
| 27 | + T_MICRO, | ||
| 28 | + T_MILLI, | ||
| 29 | + T_SECONDS | ||
| 30 | +}; | ||
| 31 | + | ||
| 32 | +std::uint64_t getEpochUSecs() | ||
| 33 | +{ | ||
| 34 | + auto tsUSec = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()); | ||
| 35 | + return static_cast<std::uint64_t>(tsUSec.time_since_epoch().count()); | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +void sleepcp( int number, TIME_RES resolution = T_MILLI ) // Cross-platform sleep function | ||
| 39 | +{ | ||
| 40 | + int factor = 0; // Should not happen.. | ||
| 41 | + | ||
| 42 | + switch( resolution ) | ||
| 43 | + { | ||
| 44 | + case T_MICRO: | ||
| 45 | + factor = 1; | ||
| 46 | + break; | ||
| 47 | + | ||
| 48 | + case T_MILLI: | ||
| 49 | + factor = 1000; | ||
| 50 | + break; | ||
| 51 | + | ||
| 52 | + case T_SECONDS: | ||
| 53 | + factor = 1000000; | ||
| 54 | + break; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + usleep( number * factor ); | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +void Subscribe() | ||
| 61 | +{ | ||
| 62 | + for( const auto &message_topic : vecTopics) | ||
| 63 | + { | ||
| 64 | + std::cout << "Subscribing to : " << message_topic << std::endl; | ||
| 65 | + oClient.subscribe(message_topic, 1, [](const osdev::components::mqtt::MqttMessage &message) | ||
| 66 | + { | ||
| 67 | + std::cout << "Received Topic : [" << message.topic() << "] Payload : " << message.payload() << std::endl; | ||
| 68 | + }); | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +void Unsubscribe() | ||
| 73 | +{ | ||
| 74 | + for( const auto &message_topic : vecTopics) | ||
| 75 | + { | ||
| 76 | + std::cout << "Unsubscribing from : " << message_topic << std::endl; | ||
| 77 | + oClient.unsubscribe(message_topic, 1); | ||
| 78 | + } | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +int main(int argc, char* argv[]) | ||
| 82 | +{ | ||
| 83 | + (void)argc; | ||
| 84 | + (void)argv; | ||
| 85 | + | ||
| 86 | + oClient.connect("localhost", 1883, Credentials()); | ||
| 87 | + | ||
| 88 | + // First create all subscriptions | ||
| 89 | + Subscribe(); | ||
| 90 | + sleepcp(1, T_SECONDS); | ||
| 91 | + | ||
| 92 | + while(1) | ||
| 93 | + { | ||
| 94 | + Unsubscribe(); | ||
| 95 | + sleepcp(1, T_SECONDS); | ||
| 96 | + Subscribe(); | ||
| 97 | + sleepcp(10, T_SECONDS); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | +} |
src/CMakeLists.txt
| @@ -15,31 +15,31 @@ include_directories( | @@ -15,31 +15,31 @@ include_directories( | ||
| 15 | set(SRC_LIST | 15 | set(SRC_LIST |
| 16 | ${CMAKE_CURRENT_SOURCE_DIR}/log.cpp | 16 | ${CMAKE_CURRENT_SOURCE_DIR}/log.cpp |
| 17 | ${CMAKE_CURRENT_SOURCE_DIR}/threadcontext.cpp | 17 | ${CMAKE_CURRENT_SOURCE_DIR}/threadcontext.cpp |
| 18 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttpublisherbase.cpp | ||
| 19 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttsubscriberbase.cpp | ||
| 20 | - ${CMAKE_CURRENT_SOURCE_DIR}/clientpaho.cpp | ||
| 21 | - ${CMAKE_CURRENT_SOURCE_DIR}/commondefs.cpp | ||
| 22 | - ${CMAKE_CURRENT_SOURCE_DIR}/connectionstatus.cpp | ||
| 23 | - ${CMAKE_CURRENT_SOURCE_DIR}/credentials.cpp | ||
| 24 | - ${CMAKE_CURRENT_SOURCE_DIR}/errorcode.cpp | ||
| 25 | - ${CMAKE_CURRENT_SOURCE_DIR}/token.cpp | ||
| 26 | - ${CMAKE_CURRENT_SOURCE_DIR}/ihistogram.cpp | ||
| 27 | - ${CMAKE_CURRENT_SOURCE_DIR}/timemeasurement.cpp | ||
| 28 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttidgenerator.cpp | ||
| 29 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqtttypeconverter.cpp | ||
| 30 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttutil.cpp | ||
| 31 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttmessage.cpp | ||
| 32 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttclient.cpp | ||
| 33 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttfailure.cpp | ||
| 34 | - ${CMAKE_CURRENT_SOURCE_DIR}/mqttsuccess.cpp | ||
| 35 | - ${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp | ||
| 36 | - ${CMAKE_CURRENT_SOURCE_DIR}/imqttclientimpl.cpp | ||
| 37 | - ${CMAKE_CURRENT_SOURCE_DIR}/istatecallback.cpp | ||
| 38 | - ${CMAKE_CURRENT_SOURCE_DIR}/scopeguard.cpp | ||
| 39 | - ${CMAKE_CURRENT_SOURCE_DIR}/serverstate.cpp | ||
| 40 | - ${CMAKE_CURRENT_SOURCE_DIR}/sharedreaderlock.cpp | ||
| 41 | - ${CMAKE_CURRENT_SOURCE_DIR}/stringutils.cpp | ||
| 42 | - ${CMAKE_CURRENT_SOURCE_DIR}/uriparser.cpp | 18 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttpublisherbase.cpp |
| 19 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttsubscriberbase.cpp | ||
| 20 | + ${CMAKE_CURRENT_SOURCE_DIR}/clientpaho.cpp | ||
| 21 | + ${CMAKE_CURRENT_SOURCE_DIR}/commondefs.cpp | ||
| 22 | + ${CMAKE_CURRENT_SOURCE_DIR}/connectionstatus.cpp | ||
| 23 | + ${CMAKE_CURRENT_SOURCE_DIR}/credentials.cpp | ||
| 24 | + ${CMAKE_CURRENT_SOURCE_DIR}/errorcode.cpp | ||
| 25 | + ${CMAKE_CURRENT_SOURCE_DIR}/token.cpp | ||
| 26 | + ${CMAKE_CURRENT_SOURCE_DIR}/ihistogram.cpp | ||
| 27 | + ${CMAKE_CURRENT_SOURCE_DIR}/timemeasurement.cpp | ||
| 28 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttidgenerator.cpp | ||
| 29 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqtttypeconverter.cpp | ||
| 30 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttutil.cpp | ||
| 31 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttmessage.cpp | ||
| 32 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttclient.cpp | ||
| 33 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttfailure.cpp | ||
| 34 | + ${CMAKE_CURRENT_SOURCE_DIR}/mqttsuccess.cpp | ||
| 35 | + ${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp | ||
| 36 | + ${CMAKE_CURRENT_SOURCE_DIR}/imqttclientimpl.cpp | ||
| 37 | + ${CMAKE_CURRENT_SOURCE_DIR}/istatecallback.cpp | ||
| 38 | + ${CMAKE_CURRENT_SOURCE_DIR}/scopeguard.cpp | ||
| 39 | + ${CMAKE_CURRENT_SOURCE_DIR}/serverstate.cpp | ||
| 40 | + ${CMAKE_CURRENT_SOURCE_DIR}/sharedreaderlock.cpp | ||
| 41 | + ${CMAKE_CURRENT_SOURCE_DIR}/stringutils.cpp | ||
| 42 | + ${CMAKE_CURRENT_SOURCE_DIR}/uriparser.cpp | ||
| 43 | ) | 43 | ) |
| 44 | 44 | ||
| 45 | include(library) | 45 | include(library) |
src/clientpaho.cpp
| @@ -515,6 +515,19 @@ std::int32_t ClientPaho::unsubscribe( const std::string& topic, int qos ) | @@ -515,6 +515,19 @@ std::int32_t ClientPaho::unsubscribe( const std::string& topic, int qos ) | ||
| 515 | break; | 515 | break; |
| 516 | } | 516 | } |
| 517 | } | 517 | } |
| 518 | + | ||
| 519 | + if(!found) // Probably not found in subscriptions, also check the pendings. | ||
| 520 | + { | ||
| 521 | + for( const auto &s : m_pendingSubscriptions ) | ||
| 522 | + { | ||
| 523 | + if( topic == s.first && qos == s.second.qos ) | ||
| 524 | + { | ||
| 525 | + found = true; | ||
| 526 | + break; | ||
| 527 | + } | ||
| 528 | + } | ||
| 529 | + } | ||
| 530 | + | ||
| 518 | if( !found ) | 531 | if( !found ) |
| 519 | { | 532 | { |
| 520 | return -1; | 533 | return -1; |
src/mqttclient.cpp
| @@ -313,6 +313,7 @@ std::set<Token> MqttClient::unsubscribe(const std::string& topic, int qos) | @@ -313,6 +313,7 @@ std::set<Token> MqttClient::unsubscribe(const std::string& topic, int qos) | ||
| 313 | // Throw (MqttException, "Not connected"); | 313 | // Throw (MqttException, "Not connected"); |
| 314 | return std::set<Token>(); | 314 | return std::set<Token>(); |
| 315 | } | 315 | } |
| 316 | + | ||
| 316 | clients.push_back(m_principalClient.get()); | 317 | clients.push_back(m_principalClient.get()); |
| 317 | for (const auto& c : m_additionalClients) | 318 | for (const auto& c : m_additionalClients) |
| 318 | { | 319 | { |