Merged
Merge Request #2 · created by Peter M. Groen


Feat/pgroen/pure virtual public interface


From feat/pgroen/pure_virtual_public_interface into development

Merged by Peter M. Groen

Source branch has been removed
2 participants



README.md
... ... @@ -41,4 +41,115 @@ later the "pub" part. If all went well, you should see two screens in sync runni
41 41 Open terminal 2
42 42 $ bin/test_mqtt_pub
43 43 ```
44   -Screen 2 is sending, Screen 1 is receiving.
45 44 \ No newline at end of file
  45 +Screen 2 is sending, Screen 1 is receiving.
  46 +
  47 +# Using the library.
  48 +Using mqtt-cpp is pretty straight forward. No real magic is happening. Beware of the fact that the library uses the namespace :
  49 +```
  50 + osdev::components::mqtt
  51 +```
  52 +
  53 +## Publishing..
  54 +To create a publisher, a simple member needs to be created.
  55 +Header :
  56 +```
  57 + #pragma once
  58 +
  59 + // std
  60 + #include <memory>
  61 + #include <string>
  62 +
  63 + // osdev::components::mqtt
  64 + #include "mqttclient.h"
  65 + #include "compat-c++14.h"
  66 +
  67 + class Publisher
  68 + {
  69 + public:
  70 + Publisher(const std::string &client_id);
  71 +
  72 + virtual ~Publisher() {}
  73 +
  74 + void connect( const std::string &hostname, int portnumber = 1883, const std::string &username = std::string(), const std::string &password = std::string() );
  75 +
  76 + void publish( const std::string &message_topic, const std::string &message_payload );
  77 +
  78 + private:
  79 + osdev::components::mqtt::MqttClient m_mqtt_client;
  80 + };
  81 +```
  82 +
  83 +Implementation
  84 +```
  85 +
  86 + // osdev::components::mqtt
  87 + // #include "token.h"
  88 +
  89 + // mqtt_tests
  90 + #include "publisher.h"
  91 +
  92 + Publisher::Publisher(const std::string &client_id)
  93 + : m_mqtt_client( client_id )
  94 + {
  95 +
  96 + }
  97 +
  98 + void Publisher::connect( const std::string &hostname, int portnumber, const std::string &username, const std::string &password )
  99 + {
  100 + m_mqtt_client.connect( hostname, portnumber, osdev::components::mqtt::Credentials( username, password ) );
  101 + std::cout << "Client state : " << m_mqtt_client.state() << std::endl;
  102 + }
  103 +
  104 + void Publisher::publish( const std::string &message_topic, const std::string &message_payload )
  105 + {
  106 + osdev::components::mqtt::MqttMessage message( message_topic, true, false, message_payload );
  107 + std::cout << "[Publisher::publish] - Publising message : " << message_payload << " to topic : " << message_topic << std::endl;
  108 + osdev::components::mqtt::Token t_result = m_mqtt_client.publish( message, 0 );
  109 + }
  110 +```
  111 +
  112 +## Subscribing
  113 +TO create a subscriber, a bit more work is involved. A subscription is dependant on a callback in which the data is handled to your liking. It is necessary to inherit from MqttSubscriberBase and override the "receive_data" method.
  114 +
  115 +subscriber.h
  116 +```
  117 +#pragma once
  118 +
  119 +// std
  120 +#include <string>
  121 +
  122 +// mqtt-cpp
  123 +#include "mqttsubscriberbase.h"
  124 +
  125 +class Subscriber : public MqttSubscriberBase
  126 +{
  127 +public:
  128 + Subscriber( const std::string &client_id );
  129 +
  130 + virtual ~Subscriber() {}
  131 +
  132 +protected:
  133 + void receive_data( const std::string &message_topic, const std::string &message_payload );
  134 +
  135 +};
  136 +```
  137 +
  138 +In the receive_data, the logic will be implemented to handle, decode and store the payload.
  139 +```
  140 +#include "subscriber.h"
  141 +
  142 +#include <iostream>
  143 +
  144 +Subscriber::Subscriber( const std::string &client_id )
  145 + : MqttSubscriberBase( client_id )
  146 +{
  147 +
  148 +}
  149 +
  150 +void Subscriber::receive_data( const std::string &message_topic, const std::string &message_payload )
  151 +{
  152 + std::cout << "[Subscriber::receive_data] - Received message : " << message_payload << " from topic : " << message_topic << std::endl;
  153 +}
  154 +```
  155 +
  156 +Now it will be very easy to send and receive messages from a broker without the hassle of administration.
... ...
examples/pub/CMakeLists.txt
... ... @@ -5,7 +5,7 @@ include(projectheader)
5 5 project_header(test_mqtt_pub)
6 6  
7 7 include_directories( SYSTEM
8   - ${CMAKE_CURRENT_SOURCE_DIR}/../../src
  8 + ${CMAKE_CURRENT_SOURCE_DIR}/../../include
9 9 )
10 10  
11 11 include(compiler)
... ... @@ -21,7 +21,7 @@ add_executable( ${PROJECT_NAME}
21 21  
22 22 target_link_libraries(
23 23 ${PROJECT_NAME}
24   - mqtt
  24 + mqtt-cpp
25 25 )
26 26  
27 27 set_target_properties( ${PROJECT_NAME} PROPERTIES
... ...
examples/pub/main.cpp
... ... @@ -83,14 +83,18 @@ int main( int argc, char* argv[] )
83 83 // Assume we are connected now, start publishing.
84 84 while( 1 )
85 85 {
86   - std::string payload = "<Timestamp value=\"" + std::to_string( getEpochUSecs() ) + "\" /><MessageNumber value=\"" + std::to_string( messageNumber ) + "\" />" ;
87   - pPublisher->publish( std::string( "test/publisher/TestPublisher" ), payload );
88   -
89   - sleepcp( 1, T_SECONDS );
90   - if( messageNumber > 2000000000 )
91   - messageNumber = -1;
92   -
93   - messageNumber++;
  86 + for( unsigned int nCount = 0; nCount < 10; nCount++ )
  87 + {
  88 + std::string payload = "<Timestamp value=\"" + std::to_string( getEpochUSecs() ) + "\" /><MessageNumber value=\"" + std::to_string( messageNumber ) + "\" />" ;
  89 + pPublisher->publish( std::string( "test/publisher/TestPublisher_" + std::to_string( nCount ) ), payload );
  90 +
  91 + if( messageNumber > 2000000000 )
  92 + {
  93 + messageNumber = -1;
  94 + }
  95 + messageNumber++;
  96 + }
  97 + sleepcp( 1, T_MICRO );
94 98 }
95 99 }
96 100 else
... ...
examples/pub/publisher.cpp
... ... @@ -20,9 +20,6 @@
20 20 * DEALINGS IN THE SOFTWARE. *
21 21 * ***************************************************************************/
22 22  
23   -// osdev::components::mqtt
24   -#include "token.h"
25   -
26 23 // mqtt_tests
27 24 #include "publisher.h"
28 25  
... ...
examples/sub/CMakeLists.txt
... ... @@ -5,7 +5,7 @@ include(projectheader)
5 5 project_header(test_mqtt_sub)
6 6  
7 7 include_directories( SYSTEM
8   - ${CMAKE_CURRENT_SOURCE_DIR}/../../src
  8 + ${CMAKE_CURRENT_SOURCE_DIR}/../../include
9 9 )
10 10  
11 11 include(compiler)
... ... @@ -21,7 +21,7 @@ add_executable( ${PROJECT_NAME}
21 21  
22 22 target_link_libraries(
23 23 ${PROJECT_NAME}
24   - mqtt
  24 + mqtt-cpp
25 25 )
26 26  
27 27 set_target_properties( ${PROJECT_NAME} PROPERTIES
... ...
examples/sub/main.cpp
... ... @@ -71,19 +71,19 @@ int main( int argc, char* argv[] )
71 71  
72 72 std::cout << "Creating the subscriber : ";
73 73 // Create the subscriber
74   - Subscriber *pSubscriber = new Subscriber();
  74 + Subscriber *pSubscriber = new Subscriber( "Test_Subscriber" );
75 75 if( pSubscriber != nullptr )
76 76 {
77 77 std::cout << "[OK]" << std::endl;
78 78 std::cout << "Connecting to the test-broker : " << std::endl;
79 79 pSubscriber->connect( "localhost", 1883, "", "" );
80 80 std::cout << "Subscribing to the test-topic....." << std::endl;
81   - pSubscriber->subscribe( "test/publisher/TestPublisher" );
  81 + pSubscriber->subscribe( "test/publisher/#" );
82 82  
83 83 // Start a loop to give the subscriber the possibility to do its work.
84 84 while( 1 )
85 85 {
86   - sleepcp( 1, T_SECONDS ); // Sleep 1 Sec to give the scheduler the change to interfene.
  86 + sleepcp( 1, T_MICRO ); // Sleep 1 Sec to give the scheduler the change to interfene.
87 87 }
88 88 }
89 89 else
... ...
examples/sub/subscriber.cpp
... ... @@ -20,27 +20,13 @@
20 20 * DEALINGS IN THE SOFTWARE. *
21 21 * ***************************************************************************/
22 22 #include "subscriber.h"
23   -#include "mqttmessage.h"
24   -#include "credentials.h"
25 23  
26   -Subscriber::Subscriber()
27   - : m_mqtt_client( "TestSubscriber" )
28   -{
29   -
30   -}
  24 +#include <iostream>
31 25  
32   -void Subscriber::connect( const std::string &hostname, int portnumber, const std::string &username, const std::string &password )
  26 +Subscriber::Subscriber( const std::string &client_id )
  27 + : MqttSubscriberBase( client_id )
33 28 {
34   - m_mqtt_client.connect( hostname, portnumber, osdev::components::mqtt::Credentials( username, password ) );
35   - std::cout << "Client state : " << m_mqtt_client.state() << std::endl;
36   -}
37 29  
38   -void Subscriber::subscribe( const std::string &message_topic )
39   -{
40   - m_mqtt_client.subscribe( message_topic, 1, [this](const osdev::components::mqtt::MqttMessage &message)
41   - {
42   - this->receive_data(message.topic(), message.payload() );
43   - });
44 30 }
45 31  
46 32 void Subscriber::receive_data( const std::string &message_topic, const std::string &message_payload )
... ...
examples/sub/subscriber.h
... ... @@ -22,27 +22,19 @@
22 22 #pragma once
23 23  
24 24 // std
25   -#include <memory>
26 25 #include <string>
27 26  
28   -// osdev::components::mqtt
29   -#include "mqttclient.h"
30   -#include "compat-c++14.h"
  27 +// mqtt-cpp
  28 +#include "mqttsubscriberbase.h"
31 29  
32   -class Subscriber
  30 +class Subscriber : public MqttSubscriberBase
33 31 {
34 32 public:
35   - Subscriber();
  33 + Subscriber( const std::string &client_id );
36 34  
37 35 virtual ~Subscriber() {}
38 36  
39   - void connect( const std::string &hostname, int portnumber, const std::string &username, const std::string &password );
40   -
41   - void subscribe( const std::string &message_topic );
42   -
43   -private:
  37 +protected:
44 38 void receive_data( const std::string &message_topic, const std::string &message_payload );
45 39  
46   -private:
47   - osdev::components::mqtt::MqttClient m_mqtt_client;
48 40 };
... ...
src/bimap.h renamed to include/bimap.h
src/clientpaho.h renamed to include/clientpaho.h
src/commondefs.h renamed to include/commondefs.h
src/compat-c++14.h renamed to include/compat-c++14.h
src/compat-chrono.h renamed to include/compat-chrono.h
... ... @@ -48,7 +48,11 @@ To ceil(const std::chrono::duration&lt;Rep, Period&gt;&amp; d)
48 48 {
49 49 To t = std::chrono::duration_cast<To>(d);
50 50 if (t < d)
  51 + {
51 52 return t + To{ 1 };
  53 + }
  54 +
  55 + // or else...
52 56 return t;
53 57 }
54 58  
... ...
src/compiletimedigits.h renamed to include/compiletimedigits.h
src/compiletimestring.h renamed to include/compiletimestring.h
src/connectionstatus.h renamed to include/connectionstatus.h
src/credentials.h renamed to include/credentials.h
src/date.h renamed to include/date.h
src/errorcode.h renamed to include/errorcode.h
src/histogram.h renamed to include/histogram.h
src/histogramprovider.h renamed to include/histogramprovider.h
src/ihistogram.h renamed to include/ihistogram.h
src/imqttclient.h renamed to include/imqttclient.h
src/imqttclientimpl.h renamed to include/imqttclientimpl.h
src/istatecallback.h renamed to include/istatecallback.h
src/lockguard.h renamed to include/lockguard.h
src/macrodefs.h renamed to include/macrodefs.h
src/measure.h renamed to include/measure.h
src/metaprogrammingdefs.h renamed to include/metaprogrammingdefs.h
src/mqttclient.h renamed to include/mqttclient.h
src/mqttfailure.h renamed to include/mqttfailure.h
src/mqttidgenerator.h renamed to include/mqttidgenerator.h
src/mqttmessage.h renamed to include/mqttmessage.h
include/mqttpublisherbase.h 0 → 100644
src/mqttstream.h renamed to include/mqttstream.h
include/mqttsubscriberbase.h 0 → 100644
  1 +/* ****************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a *
  5 + * copy of this software and associated documentation files (the "Software"), *
  6 + * to deal in the Software without restriction, including without limitation *
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  8 + * and/or sell copies of the Software, and to permit persons to whom the *
  9 + * Software is furnished to do so, subject to the following conditions: *
  10 + * *
  11 + * The above copyright notice and this permission notice shall be included in *
  12 + * all copies or substantial portions of the Software. *
  13 + * *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
  17 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  18 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
  19 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
  20 + * DEALINGS IN THE SOFTWARE. *
  21 + * ***************************************************************************/
  22 +#pragma once
  23 +
  24 +// std
  25 +#include <memory>
  26 +#include <string>
  27 +
  28 +// osdev::components::mqtt
  29 +#include "mqttclient.h"
  30 +
  31 +
  32 +class MqttSubscriberBase
  33 +{
  34 +public:
  35 + /*!
  36 + * \brief SubscriberBase
  37 + */
  38 + MqttSubscriberBase( const std::string &client_id );
  39 +
  40 + /*!
  41 + * \brief ~SubscriberBase
  42 + */
  43 + virtual ~MqttSubscriberBase() {}
  44 +
  45 + /*!
  46 + * \brief getClientId
  47 + * \return
  48 + */
  49 + std::string getClientId() const;
  50 +
  51 + /*!
  52 + * \brief connect
  53 + * \param hostname
  54 + * \param portnumber
  55 + * \param username
  56 + * \param password
  57 + */
  58 + void connect( const std::string &hostname, int portnumber, const std::string &username, const std::string &password );
  59 +
  60 + /*!
  61 + * \brief subscribe
  62 + * \param message_topic
  63 + */
  64 + void subscribe( const std::string &message_topic );
  65 +
  66 + /*!
  67 + * \brief disconnect
  68 + */
  69 + void disconnect();
  70 +
  71 +protected:
  72 + /*!
  73 + * \brief receive_data
  74 + * \param message_topic
  75 + * \param message_payload
  76 + */
  77 + virtual void receive_data( const std::string &message_topic, const std::string &message_payload ) = 0;
  78 +
  79 +private:
  80 + osdev::components::mqtt::MqttClient m_mqtt_client;
  81 +
  82 +};
... ...
src/mqttsuccess.h renamed to include/mqttsuccess.h
src/mqtttypeconverter.h renamed to include/mqtttypeconverter.h
src/mqttutil.h renamed to include/mqttutil.h
src/scopeguard.h renamed to include/scopeguard.h
src/serverstate.h renamed to include/serverstate.h
src/sharedreaderlock.h renamed to include/sharedreaderlock.h
src/stringify.h renamed to include/stringify.h
src/stringutils.h renamed to include/stringutils.h
src/synchronizedqueue.h renamed to include/synchronizedqueue.h
src/timemeasurement.h renamed to include/timemeasurement.h
src/token.h renamed to include/token.h
src/uriparser.h renamed to include/uriparser.h
src/uriutils.h renamed to include/uriutils.h
src/utils.h renamed to include/utils.h
src/CMakeLists.txt
... ... @@ -23,22 +23,22 @@ endif()
23 23 # ==============================================================================
24 24 include(projectheader)
25 25  
26   -project_header(mqtt)
  26 +project_header(mqtt-cpp)
27 27  
28 28 find_package( Boost REQUIRED COMPONENTS regex )
29 29  
30 30 include(compiler)
31 31  
32 32 include_directories(
33   - ${CMAKE_CURRENT_SOURCE_DIR}/../logutils
  33 + ${CMAKE_SOURCE_DIR}/include
34 34 )
35 35  
36 36 set(SRC_LIST
  37 + ${CMAKE_CURRENT_SOURCE_DIR}/mqttpublisherbase.cpp
  38 + ${CMAKE_CURRENT_SOURCE_DIR}/mqttsubscriberbase.cpp
37 39 ${CMAKE_CURRENT_SOURCE_DIR}/clientpaho.cpp
38 40 ${CMAKE_CURRENT_SOURCE_DIR}/commondefs.cpp
39 41 ${CMAKE_CURRENT_SOURCE_DIR}/connectionstatus.cpp
40   - ${CMAKE_CURRENT_SOURCE_DIR}/compiletimedigits.h
41   - ${CMAKE_CURRENT_SOURCE_DIR}/compiletimestring.h
42 42 ${CMAKE_CURRENT_SOURCE_DIR}/credentials.cpp
43 43 ${CMAKE_CURRENT_SOURCE_DIR}/errorcode.cpp
44 44 ${CMAKE_CURRENT_SOURCE_DIR}/token.cpp
... ... @@ -59,24 +59,6 @@ set(SRC_LIST
59 59 ${CMAKE_CURRENT_SOURCE_DIR}/sharedreaderlock.cpp
60 60 ${CMAKE_CURRENT_SOURCE_DIR}/stringutils.cpp
61 61 ${CMAKE_CURRENT_SOURCE_DIR}/uriparser.cpp
62   - # Helper files ( Utillities )
63   - ${CMAKE_CURRENT_SOURCE_DIR}/bimap.h
64   - ${CMAKE_CURRENT_SOURCE_DIR}/compat-c++14.h
65   - ${CMAKE_CURRENT_SOURCE_DIR}/compat-chrono.h
66   - ${CMAKE_CURRENT_SOURCE_DIR}/histogram.h
67   - ${CMAKE_CURRENT_SOURCE_DIR}/histogramprovider.h
68   - ${CMAKE_CURRENT_SOURCE_DIR}/imqttclient.h
69   - ${CMAKE_CURRENT_SOURCE_DIR}/imqttclientimpl.h
70   - ${CMAKE_CURRENT_SOURCE_DIR}/lockguard.h
71   - ${CMAKE_CURRENT_SOURCE_DIR}/macrodefs.h
72   - ${CMAKE_CURRENT_SOURCE_DIR}/measure.h
73   - ${CMAKE_CURRENT_SOURCE_DIR}/metaprogrammingdefs.h
74   - ${CMAKE_CURRENT_SOURCE_DIR}/mqttstream.h
75   - ${CMAKE_CURRENT_SOURCE_DIR}/stringify.h
76   - ${CMAKE_CURRENT_SOURCE_DIR}/stringutils.h
77   - ${CMAKE_CURRENT_SOURCE_DIR}/synchronizedqueue.h
78   - ${CMAKE_CURRENT_SOURCE_DIR}/utils.h
79   - ${CMAKE_CURRENT_SOURCE_DIR}/uriutils.h
80 62 )
81 63  
82 64 include(library)
... ...
src/mqttpublisherbase.cpp 0 → 100644
src/mqttsubscriberbase.cpp 0 → 100644
  1 +/* ****************************************************************************
  2 + * Copyright 2019 Open Systems Development BV *
  3 + * *
  4 + * Permission is hereby granted, free of charge, to any person obtaining a *
  5 + * copy of this software and associated documentation files (the "Software"), *
  6 + * to deal in the Software without restriction, including without limitation *
  7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
  8 + * and/or sell copies of the Software, and to permit persons to whom the *
  9 + * Software is furnished to do so, subject to the following conditions: *
  10 + * *
  11 + * The above copyright notice and this permission notice shall be included in *
  12 + * all copies or substantial portions of the Software. *
  13 + * *
  14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
  15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
  16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
  17 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
  18 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
  19 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
  20 + * DEALINGS IN THE SOFTWARE. *
  21 + * ***************************************************************************/
  22 +
  23 +// osdev::components::mqtt
  24 +#include "mqttclient.h"
  25 +#include "mqttsubscriberbase.h"
  26 +#include "mqttmessage.h"
  27 +#include "credentials.h"
  28 +
  29 +MqttSubscriberBase::MqttSubscriberBase( const std::string &client_id )
  30 + : m_mqtt_client( client_id )
  31 +{
  32 +
  33 +}
  34 +
  35 +std::string MqttSubscriberBase::getClientId() const
  36 +{
  37 + return m_mqtt_client.clientId();
  38 +}
  39 +
  40 +void MqttSubscriberBase::connect(const std::string &hostname, int portnumber,
  41 + const std::string &username, const std::string &password)
  42 +{
  43 + m_mqtt_client.connect( hostname, portnumber, osdev::components::mqtt::Credentials( username, password ) );
  44 +}
  45 +
  46 +void MqttSubscriberBase::subscribe( const std::string &message_topic )
  47 +{
  48 + m_mqtt_client.subscribe( message_topic, 1, [this]( const osdev::components::mqtt::MqttMessage &message )
  49 + {
  50 + this->receive_data( message.topic(), message.payload() );
  51 + });
  52 +}
  53 +
  54 +void MqttSubscriberBase::disconnect()
  55 +{
  56 + m_mqtt_client.disconnect();
  57 +}
... ...