libmosquittoppでのMQTT操作

MQTT通信する際にPythonでは少し遅く感じる、既存のC++プログラムに組み込みたいということもあると思う。そこではC++でのMQTT通信の実装方法の例を説明する。




サンプルコード


最初にMQTTクライアントのサンプルコードを載せる。説明は後にしていく

参考: mosquitopp_client
参考: Mosquitto C++ sample code to publish


MQTTClient.hpp

#ifndef MQTTCLIENT
#define MQTTCLIENT
      
#include <mosquittopp.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include "GlobalVariables.hpp"
      
#define MAX_PAYLOAD 50
#define DEFAULT_KEEP_ALIVE 60
      
class MQTTClient : public mosqpp::mosquittopp {
  public:
    ~MQTTClient();
    void on_connect(int rc);
    MQTTClient(const char *_id, const char *_hostname, int _port, char *topic);
    void on_message(const struct mosquitto_message *message);
    void on_subscribe(int mid, int qos_count, const int *granted_qos);
    void on_publish(int mid);
    bool sendMessage(char *message, int qos, bool retain);
    bool sendMessage(int sendnum, int qos, bool retain);
    void clearMessage();
      
  private:
    const char *clientid;
    const char *hostname;
    char *topic;
    int port;
    int keepalive;
};
      
inline MQTTClient::MQTTClient(const char *_id, const char *_hostname, int _port, char *_topic) : mosquittopp(_id) {
  mosqpp::lib_init();
  clientid = _id;
  hostname = _hostname;
  port = _port;
  topic = _topic;
  keepalive = DEFAULT_KEEP_ALIVE;
  connect(hostname, port, keepalive);
}
      
inline bool MQTTClient::sendMessage(char *message, int qos = 0, bool retain = false) {
  int ret = publish(NULL, topic, strlen(message), message, qos, retain);
  return (ret == MOSQ_ERR_SUCCESS);
}
      
inline bool MQTTClient::sendMessage(int sendnum, int qos = 0, bool retain = false) {
  std::stringstream ssnum;
  ssnum.str("");
  ssnum << sendnum;
  const char *message=(ssnum.str()).c_str();
  int ret=publish(NULL, topic, strlen(message), message, qos, retain);
  return (ret==MOSQ_ERR_SUCCESS);
}

inline void MQTTClient::clearMessage() { _messages="" ; }

inline MQTTClient::~MQTTClient() { mosqpp::lib_cleanup(); }

#endif // !MQTTCLIENT

MQTTClient.cpp
#include "MQTTClient.hpp"

void MQTTClient::on_connect(int rc) {
  if (!rc) {
      std::cout << "Connected: " << clientid << "- code " << rc << std::endl; 
  } 
}

void MQTTClient::on_subscribe(int mid, int qos_count, const int *granted_qos){ 
  // std::cout << "Subscription succeeded." << std::endl;
}

void MQTTClient::on_publish(int mid){
  std::cout << "Published: " << mid << std::endl;
}

void MQTTClient::on_message(const struct mosquitto_message *message){ 
  int payload_size=MAX_PAYLOAD + 1;
  char buf[payload_size];
  if (!strcmp(message->topic, topic)) {
    memset(buf, 0, payload_size * sizeof(char));
    memcpy(buf, message->payload, MAX_PAYLOAD * sizeof(char));
    
    //実際の処理、実際にメッセージを受け取った際に行うプログラムをここに書く
  
  } else {
    std::cout << "not get message: " << buf << std::endl;
  } 
}

特に複雑な処理でない場合は上のプログラムをそのまま使う。メッセージを受け取った際にするプログラム内容はMQTTClient.cppの該当部分に書く。
on_がついている関数については、各イベント(subscribeが起きた、publishされた)が起きたときに自動で実行される。もし何か各イベントごとに処理が必要な場合はそこに書く。