M
A simple to use MQTT CPP library. Multithreaded, buffered and stable.. – README.md

README.md

MQTT-CPP

Modern, asynchronous and fast C++ client for paho-mqtt ( paho-c ).

Features:

  • Simple and clean A-synchronous API. ( Connect, publish, subscribe ).
  • Multi-threaded. Use multiple topics in multiple threads..
  • Callbacks can be lambdas, class methods, bind expressions, or any [std::function]
  • Fully autonomous reconnecting

Dependencies

This library has dependencies on libpaho-mqtt3a.so and Boost ( RegEx and Core ). Changes are there is a version for your platform ( Debian, Fedora, CentOS ). Just check your package manager for the correct package-name.

Tutorial

  • Clone this repository : git clone http://gitlab.osdev.nl/open_source/mqtt-cpp.git
    • Change to the repo and run the submodules script : $ cd mqtt-cpp $ scripts/setup_submodules -i This will add the cmake directory and versioning.
    • Create a build directory and start the build. $ mkdir build $ cd build $ cmake ../ $ gmake ( or make, depending on your platform ) And you're all set. In build/bin there are two examples, test_mqtt_pu and test_mqtt_sub. Have a broker running, like mosquitto or flashmq capable of accepting anonymous connections. Start the "sub" part and couple of moments later the "pub" part. If all went well, you should see two screens in sync running.
   Open terminal 1
   $ bin/test_mqtt_sub

   Open terminal 2
   $ bin/test_mqtt_pub

Screen 2 is sending, Screen 1 is receiving.

Using the library.

Using mqtt-cpp is pretty straight forward. No real magic is happening. Beware of the fact that the library uses the namespace :

    osdev::components::mqtt

Publishing..

To create a publisher, a simple member needs to be created. Header :

    #pragma once

    // std
    #include <memory>
    #include <string>

    // osdev::components::mqtt
    #include "mqttclient.h"
    #include "compat-c++14.h"

    class Publisher
    {
    public:
        Publisher(const std::string &client_id);

        virtual ~Publisher() {}

        void    connect( const std::string &hostname, int portnumber = 1883, const std::string &username = std::string(), const std::string &password = std::string() );

        void    publish( const std::string &message_topic, const std::string &message_payload );

    private:
        osdev::components::mqtt::MqttClient m_mqtt_client;
    };

Implementation


    // osdev::components::mqtt
    // #include "token.h"

    // mqtt_tests
    #include "publisher.h"

    Publisher::Publisher(const std::string &client_id)
        : m_mqtt_client( client_id )
    {

    }

    void Publisher::connect( const std::string &hostname, int portnumber, const std::string &username, const std::string &password )
    {
        m_mqtt_client.connect( hostname, portnumber, osdev::components::mqtt::Credentials( username, password ) );
        std::cout << "Client state : " << m_mqtt_client.state() << std::endl;
    }

    void Publisher::publish( const std::string &message_topic, const std::string &message_payload )
    {
        osdev::components::mqtt::MqttMessage message( message_topic, true, false, message_payload );
        std::cout << "[Publisher::publish] - Publising message : " << message_payload << " to topic : " << message_topic << std::endl;
        osdev::components::mqtt::Token t_result = m_mqtt_client.publish( message, 0 );
    }

Subscribing

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.

subscriber.h

#pragma once

// std
#include <string>

// mqtt-cpp
#include "mqttsubscriberbase.h"

class Subscriber : public MqttSubscriberBase
{
public:
    Subscriber( const std::string &client_id );

    virtual ~Subscriber() {}

protected:
    void receive_data( const std::string &message_topic, const std::string &message_payload );

};

In the receive_data, the logic will be implemented to handle, decode and store the payload.

#include "subscriber.h"

#include <iostream>

Subscriber::Subscriber( const std::string &client_id )
    : MqttSubscriberBase( client_id )
{

}

void Subscriber::receive_data( const std::string &message_topic, const std::string &message_payload )
{
    std::cout << "[Subscriber::receive_data] - Received message : " << message_payload << " from topic : " << message_topic << std::endl;
}

Now it will be very easy to send and receive messages from a broker without the hassle of administration.