首页 > 编程语言 >vc++2008通过paho c语言客户端接入MQTT

vc++2008通过paho c语言客户端接入MQTT

时间:2023-08-07 19:14:30浏览次数:46  
标签:MqttHelper void MQTTAsync c++ char int MQTT context 2008

因项目需要,IoT平台需要支持vc++2008接入。因为Paho的c++客户端不支持低版本vc++,所以不得不尝试通过c语言的库实现。

类库下载

从github下载c语言包。例如: eclipse-paho-mqtt-c-win32-1.3.12.zip

https://github.com/eclipse/paho.mqtt.c/releases

类库整合和配置

解压出来的c语言类库包可以看到很多库文件,详情如下图所示。不同的包适用于不同的场景,本案列用了异步客户端,所以用的是paho-mqtt3a这个系列。

 

配置步骤:

  1. 拷贝"paho-mqtt3a.dll"到vc++项目的根路径。
  2. 拷贝"paho-mqtt3a.lib"到vc++项目的"lib"目录(或其他自定义目录)。
  3. 拷贝"include"目录里面的头文件到vc++项目的"mqtt"目录(或其他自定义目录)。
  4. 在其他include目录的设置上, 把上一步的包含了mqtt头文件的".\mqtt"目录相对路径输入。 Project(right click)->Properties->Configuration Properties->C/C++->Additional Include Directories

  5. 在链接配置上, 输入mqtt库文件的相对路径"lib\paho-mqtt3a.lib"。 Project(right click)->Properties->Configuration Properties->Linker->Input->Additional Dependencies

客户端帮助类

这个帮助类会把MQTT客户端封装成单例。为了提高可靠性,启用了buffer消息文件持久化和断线自动重连。

MqttHelper.h

#include "MQTTAsync.h"

#pragma once

#define TIMEOUT     10000L
#define QOS         2
#define ADDRESS        "mqtt://xxxx.com:1883"
#define USER        "demo"
#define PASSWORD    "demo"

class MqttHelper
{
private:
    // Private constructor to prevent instantiation
    MqttHelper() {
        Connected = false;
    } 
    MqttHelper(const MqttHelper&); // Disable copy constructor
    MqttHelper& operator=(const MqttHelper&); // Disable assignment operator
    MQTTAsync client;
public:
    bool Connected;
    static MqttHelper& getInstance() {
        static MqttHelper instance;
        return instance;
    }

public:
    bool Connect();
    void Close();
    bool Subcribe(char* topic);
    bool Publish(char* topic, void*payload, int payloadLength);
    bool Publish(char* topic, void*payload, int payloadLength, int qos);

    int OnMsgReceived(void *context, char *topicName, int topicLen, MQTTAsync_message *message);
    void OnMsgPublished(void* context, MQTTAsync_token token);
    void OnConnected(void* context, MQTTAsync_successData* response);

private:
    char* GetClientId();
};

 

MqttHelper.cpp

#include "StdAfx.h"
#include "MqttHelper.h"
#include <windows.h>

void OnSuccessCallback(void* context, MQTTAsync_successData* response) {
    MqttHelper* mqttHelper = static_cast<MqttHelper*>(context);
    mqttHelper->OnConnected(context, response);
}
int OnMessageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message){
    MqttHelper* mqttHelper = static_cast<MqttHelper*>(context);
    return mqttHelper->OnMsgReceived(context, topicName, topicLen, message);
}
void OnDeliveryComplete(void* context, MQTTAsync_token token){
    MqttHelper* mqttHelper = static_cast<MqttHelper*>(context);
    mqttHelper->OnMsgPublished(context, token);
}

bool MqttHelper::Connect(){
    if (Connected){
        return true;
    }

    MQTTAsync_create(&client, ADDRESS, GetClientId(), MQTTCLIENT_PERSISTENCE_DEFAULT, NULL);

    if (MQTTAsync_setCallbacks(client, client, NULL, 
        OnMessageArrived,OnDeliveryComplete) != MQTTASYNC_SUCCESS)
    {
        return false;
    }

    MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 0;
    conn_opts.username = USER;
    conn_opts.password = PASSWORD;
    conn_opts.automaticReconnect = 1;
    conn_opts.onSuccess = OnSuccessCallback;
    conn_opts.MQTTVersion = MQTTVERSION_3_1_1;
    int rc = MQTTAsync_connect(client, &conn_opts);
    if (rc != MQTTASYNC_SUCCESS)
    {
        return false;
    }
    Connected = true;
    return true;
}

void MqttHelper::Close(){
    if (client != NULL)
    {
        MQTTAsync_disconnect(client, NULL);
        MQTTAsync_destroy(&client);
    }
}

bool MqttHelper::Subcribe(char* topic){
    int rc = MQTTAsync_subscribe(client, topic, QOS, NULL);
    if (rc != MQTTASYNC_SUCCESS)
    {
        return false;
    }
    return true;
}

bool MqttHelper::Publish(char* topic, void*payload, int payloadLength){
    return Publish(topic, payload, payloadLength, QOS);
}

bool MqttHelper::Publish(char* topic, void*payload, int payloadLength, int qos){
    MQTTAsync_responseOptions pub_opts = MQTTAsync_responseOptions_initializer;
    MQTTAsync_message pub_msg = MQTTAsync_message_initializer;
    pub_msg.payload = payload;
    pub_msg.payloadlen = payloadLength;
    pub_msg.qos = qos;
    pub_msg.retained = 0;
    int rc = MQTTAsync_sendMessage(client, topic, &pub_msg, &pub_opts);
    return  rc == MQTTASYNC_SUCCESS;
}

char* MqttHelper::GetClientId(){
    TCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD size = sizeof(computerName) / sizeof(computerName[0]);
    if (!GetComputerName(computerName, &size)){
        lstrcpy(computerName, _T("unknown"));
    }
    TCHAR path[MAX_PATH];
    TCHAR* processName;
    if (GetModuleFileName(NULL, path, sizeof(path)) != 0) {
        processName = _tcsrchr(path, '\\');
        if (processName != NULL)
            processName++; // Move past the backslash
        else
            processName = path;
    }

    TCHAR clientId[MAX_PATH];
    lstrcpy(clientId, computerName);
    lstrcat(clientId, _T("."));
    lstrcat(clientId, processName);

    int charArrayLength = WideCharToMultiByte(
        CP_ACP,                 // Code page for the conversion
        0,                      // Conversion flags (0 for default behavior)
        clientId,            // Source TCHAR array
        -1,                     // Length of the source TCHAR array (-1 for null-terminated)
        NULL,                // Destination char array
        0,                      // Size of the destination char array
        NULL,                // Default character used for conversion errors (optional)
        NULL                 // Indicates if the function used a default character (optional)
        );

    if (charArrayLength > 0) {
        char* charArray = new char[charArrayLength];
        WideCharToMultiByte(
            CP_ACP,             // Code page for the conversion
            0,                  // Conversion flags (0 for default behavior)
            clientId,        // Source TCHAR array
            -1,                 // Length of the source TCHAR array (-1 for null-terminated)
            charArray,          // Destination char array
            charArrayLength,    // Size of the destination char array
            NULL,            // Default character used for conversion errors (optional)
            NULL             // Indicates if the function used a default character (optional)
            );
        return charArray;
    }
    return "unknown";
}

int MqttHelper::OnMsgReceived(void *context, char *topicName, int topicLen, MQTTAsync_message *message){
    MQTTAsync client = (MQTTAsync)context;
    printf("Message arrived\n");
    printf("     topic: %s\n", topicName);
    printf("   message: %.*s\n", message->payloadlen, (char*)message->payload);
    MQTTAsync_freeMessage(&message);
    MQTTAsync_free(topicName);
    return 1;
}

void MqttHelper::OnMsgPublished(void* context, MQTTAsync_token token){
    printf("Message arrived\n");
    printf("     token: %d\n", token);
}

void MqttHelper::OnConnected(void* context, MQTTAsync_successData* response){
    printf("client connected\n");
    MQTTAsync client = (MQTTAsync)context;
    //subcribe topic
    /*int rc = MQTTAsync_subscribe(client, "demo/in", QOS, NULL);
    if (rc != MQTTASYNC_SUCCESS)
    {
        printf("subscribe success\n");
    }
    else
    {
        printf("subscribe failed\n");
    }*/
}
  把以上代码整合到你的项目,然后就可以通过调用"MqttHelper::getInstance().Publish("demo/test", byteData, strlen(byteData))"来发送消息了。  

用MQTTX辅助调试

  1. 下载并安装MQTTX。
    https://mqttx.app/
  2. 创建连接到MQTT broker.

  3. 连接并订阅主题"demo/#"。

     

 

转载请注明出处: https://i.cnblogs.com/posts/edit;postId=17611371



标签:MqttHelper,void,MQTTAsync,c++,char,int,MQTT,context,2008
From: https://www.cnblogs.com/keitsi/p/17611371.html

相关文章

  • 质因子分解C++
    1、题目2、AC代码#include<iostream>#include<cmath>usingnamespacestd;constintmaxn=100010;//10的5次方即可boolisPrime(intn){if(n<=1)returnfalse;if(n==2||n==3)returntrue;//特判if(n%6!=1&&n%6!=5)returnfalse;//不在6的倍......
  • 递推算法例题C++
    1、移动路线【题目描述】X桌子上有一个m行n列的方格矩阵,将每个方格用坐标表示,行坐标从下到上依次递增,列坐标从左至右依次递增,左下角方格的坐标为(1,1),则右上角方格的坐标为(m,n)。小明是个调皮的孩子,一天他捉来一只蚂蚁,不小心把蚂蚁的右脚弄伤了,于是蚂蚁只能向上或向右移动。小明......
  • vscode c++食用指南
    准备配置环境为机房的win10.首先你需要下载vscode。可以从官网下载:https://code.visualstudio.com/Download配置编译c++下载完之后安装好,界面全是英文的,正常情况下在一会儿后他会提示你安装中文的扩展,如果没有可以去最左边四个小方块的图标里搜索“Chinese”安装即可。ps:......
  • /lib64/libstdc++.so.6: version `GLIBCXX_3.4.26' not found
    原因使用的gcc没有找到对应的glib库。每个版本的glib都会有改变,所以使用的时候必须匹配。大部分是因为自己编译升级了gcc,再用新的gcc编译程序时没有找到当时匹配的类库。查找原因报错提示很明确了,/lib64/libstdc++.so.6中没有找到GLIBCXX_3.4.26版本内容。正常情况/lib64/lib......
  • STL迭代器适配器reverse_iterator剖析 #C++
    迭代器适配器(iteratoradapters)迭代器适配器是迭代器应用于迭代器的产物,包括insertiterator,reverseiterator和iostreamiterator。迭代器适配器本质是对容器或一般迭代器进行封装,以使其更加符合需求。reverse_iterator概述reverse_iterator可以将一般迭代器的行进方向进......
  • 计算两条直线夹角(C++)
    计算两条直线的锐角可以使用向量的知识来实现。在C++中,我们可以定义一个函数来计算两个向量的夹角,并根据夹角的余弦值来判断角度的大小。以下是一个用C++编写的示例代码:#include<iostream>#include<cmath>usingnamespacestd;structVector{doublex;doubley;......
  • c++中unique_ptr 的使用和理解
    unique_ptr的使用std::unique_ptr是c++11起引入的智能指针,为什么必须要在c++11起才有该特性,主要还是c++11增加了move语义,否则无法对对象的所有权进行传递。unique_ptr介绍unique_ptr不共享它的指针。它无法复制到其他unique_ptr,无法通过值传递到函数,也无法用于需要副本的......
  • 【开源三方库】Aki:一行代码极简体验JS&C++跨语言交互
     开源项目 OpenHarmony是每个人的 OpenHarmony 一、简介OpenAtom OpenHarmony(以下简称“OpenHarmony”)的前端开发语言是ArkTS,在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是JavaScript(简称JS)的超集。而Node-API(简称NAPI)是方舟引擎用于封装JS能力为......
  • c++中的weak_ptr的使用与理解
    weak_ptr的使用\(\quad\)关于为什么使用weak_ptr,以及他的使用场景,我们在这篇文章中已经进行了介绍。而对于其具体的使用方法,比如说如何通过weak_ptr访问内存中的数据等操作还未提及,这里做个简单赘述。\(\quad\)有一句话说的很好:weak_ptr就像观测者那样观测资源的使用情况......
  • C++实现高精度减法
    一、问题描述:    高精度算法是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大......