mosquito 是一个成熟的mqtt库,包含broker和对应客户端.使用时调用接口比较多,
class mosqpp_EXPORT mosquittopp {
private:
struct mosquitto *m_mosq;
public:
mosquittopp(const char *id=NULL, bool clean_session=true);
virtual ~mosquittopp();
int reinitialise(const char *id, bool clean_session);
int socket();
int will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
int will_clear();
int username_pw_set(const char *username, const char *password=NULL);
int connect(const char *host, int port=1883, int keepalive=60);
int connect_async(const char *host, int port=1883, int keepalive=60);
int connect(const char *host, int port, int keepalive, const char *bind_address);
int connect_async(const char *host, int port, int keepalive, const char *bind_address);
int reconnect();
int reconnect_async();
int disconnect();
int publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false);
int subscribe(int *mid, const char *sub, int qos=0);
int unsubscribe(int *mid, const char *sub);
void reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff);
int max_inflight_messages_set(unsigned int max_inflight_messages);
void message_retry_set(unsigned int message_retry);
void user_data_set(void *userdata);
int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL);
int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
int tls_insecure_set(bool value);
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
int opts_set(enum mosq_opt_t option, void *value);
int loop(int timeout=-1, int max_packets=1);
int loop_misc();
int loop_read(int max_packets=1);
int loop_write(int max_packets=1);
int loop_forever(int timeout=-1, int max_packets=1);
int loop_start();
int loop_stop(bool force=false);
bool want_write();
int threaded_set(bool threaded=true);
int socks5_set(const char *host, int port=1080, const char *username=NULL, const char *password=NULL);
// names in the functions commented to prevent unused parameter warning
virtual void on_connect(int /*rc*/) {return;}
virtual void on_disconnect(int /*rc*/) {return;}
virtual void on_publish(int /*mid*/) {return;}
virtual void on_message(const struct mosquitto_message * /*message*/) {return;}
virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int * /*granted_qos*/) {return;}
virtual void on_unsubscribe(int /*mid*/) {return;}
virtual void on_log(int /*level*/, const char * /*str*/) {return;}
virtual void on_error() {return;}
};
在常规使用用过程中,我们根本用不了这么多接口,而且订阅消息的回调函数包含所有信息,在使用时只能以分发的方式来处理消息内容.因此,能不能将消息和业务绑定,消息回调只是负责接收消息,而不处理消息?
肯定是可以的,我的设计是在订阅消息的时候就将要订阅的消息和需要这条消息的业务接口关联到一起(定义一个map,key是topic字符串,value是业务接口函数);收到消息后根据topic字符串招单对应业务函数接口,即可实现消息和业务的绑定.
考虑到实际使用的便捷性,将重联功能也以状态机的方式重新封装,封装后的接口:
public:
MQC(const char *mqcID);
~MQC();
void mqcInit(const vMqcCfg &mqcCfg);
void mqcInit(const std::string &server_ip, const int &server_port, const int &keepalive);
void mqcStart();
void mqcExit();
int mqcPublish(const vMqcMessge pubMessge);
int mqcSubscrible(const std::string subTopic, std::function<void(std::string &)> subMsgCbFunc);
void mqcRegistCallback(std::function<void(std::string &)> msg_callback);
uint64_t getCurrenTimeMs();
业务接口函数既可以是普通函数,也可以是类成员函数,使用方式:
#include <string.h>
#include <iostream>
#include <mqc.h>
mqc::MQC mqc_obj("navchip_server");
class TEST
{
public:
TEST(){};
~TEST(){};
void callback(std::string &msg)
{
std::cout << "test class: " << msg << std::endl;
};
};
void topic_1_callbacl(std::string &msg)
{
std::cout << "msg: " << msg << std::endl;
}
int main(int argc, char **argv)
{
mqc::vMqcCfg mqc_cfg("127.0.0.1", 1883, 60);
mqc_obj.mqcInit(mqc_cfg);
mqc_obj.mqcStart();
std::string topic_1 = "/topic/test";
std::string topic_2 = "/topic/test/1";
std::string topic_3 = "/topic/test/3";
TEST test1;
mqc_obj.mqcSubscrible(topic_2, std::function<void(std::string &)>(topic_1_callbacl));
mqc_obj.mqcSubscrible(topic_1, std::bind(&TEST::callback, &test1, std::placeholders::_1));
mqc_obj.mqcSubscrible(topic_3, NULL);
std::cout << "---- start----" << std::endl;
while (1)
{
std::string topic = "/sensor/lidar/cloud_points_drc";
mqc::vMqcMessge test;
test.topic = topic;
test.payload = "dfasfasfa";
test.payloadlen = 8;
mqc_obj.mqcPublish(test);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
mqc_obj.mqcExit();
return 0;
}
mosquito 已经编译了ARM64和X64的库,都在工程里面,资源地址
https://download.csdn.net/download/qq_33635623/21397428?spm=1001.2014.3001.5503
.
├── bin
│ └── mqc_app
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ └── Makefile
├── CMakeLists.txt
├── inc
│ └── mqc.h
├── lib
│ ├── libmosquito_arm64
│ └── libmosquito_x86_64
└── src
├── main.cpp
└── mqc.cpp
测试结果: