mqtt 库编译及示例

1,源码地址 git clone https://github.com/eclipse/paho.mqtt.c.git,下载即可。

2,编译库

下载源码后,cd paho.mqtt.c目录下,直接make就能编译出动态库,如果想更方便使用,可以再执行make install 。但我这里编译的是静态库,执行了:cmake . -DPAHO_BUILD_STATIC=TRUE,然后make,完成后在src目录下会生成静态库libpaho-mqtt3a.a。编译mqtt库失败可能是一些依赖库,上网搜索安装相关库即可。

3,示例使用

1)下载一个mqtt客户端,地址:http://www.jensd.de/apps/mqttfx/1.7.1/ 

 进入目录1.7.1里去下载,我下载了倒数第二个进行了安装,结果安装完启动时需要填入序列号而没法使用。进入1.7.1选择适合版本,如:

我选择了windows-x64版本的,下载安装。

2)免费的mqtt 服务:broker-cn.emqx.io

软件安装完成后,打开进行服务器设置,如下:

 进行连接后,最右圆图为绿色表示连接成功,然后就可以进行订阅/发布

 3)代码示例

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "MqttClientImpl.h"

int main()
{
    Json::Value brokerInfo;
    brokerInfo["host"] = "tcp://broker-cn.emqx.io"; //免费的mqtt broker,和mqtt fx软件填写一样
    brokerInfo["userName"] = "test";    //用户名其实用不到
    brokerInfo["password"] = "111";     //密码其实用不到
    brokerInfo["clientId"] = "111111";  
    brokerInfo["port"] = 1883;

    bool iRet = MQTT::CMqttClientImpl::instance()->initialize(brokerInfo);
    printf("initialize mqtt iRet = %d\n", iRet);
    if(iRet)
    {
        //iRet = MQTT::CMqttClientImpl::instance()->publishMessage("liangshen_mqtt", "liangshen mqtt test!");
        printf("mqtt publish message iRet = %d\n", iRet);
    }

    while (1)
    {
        /* code */
    }
    
    return 0;
}
void onConnect(void* context, MQTTAsync_successData* message)
{
    printf("connect to server success\n");
    MQTTAsync client = (MQTTAsync)context;
    MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;

    //进行订阅
    opts.onSuccess = onSubscribe;
    opts.onFailure = onSubscribeFailure;
    opts.context = client;
    
    std::string topic = "MQTT_example";
    int retCode = MQTTAsync_subscribe(client, topic.c_str(), 1, &opts);
    if (retCode != MQTTASYNC_SUCCESS) 
    {
        printf("Failed to start subscribe, return code %d\n", retCode);
    }
    printf("subscribe topic[%s] success!\n", topic.c_str());
}

示例里订阅了主题“MQTT_example”,即连接成功后进行了订阅,运行后,在mqtt fx客户端进行主题发布,如下:

在Publish发布后,程序能接收到正确信息,同时程序会发布一个主题消息,接收消息和发布主题代码如下 :

/*
* @brief 消息接收回调
*/
int32_t messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message) 
{
    static int count = 0;
    std::string subMessage((char *)message->payload, message->payloadlen);
    std::string topic(topicName, topicLen);
    
    CMqttClientImpl::instance()->handleMessage(topicName, subMessage);


    //每次调用完需要释放,否则接收的消息一直是第一次的
    MQTTAsync_freeMessage(&message);
    MQTTAsync_free(topicName);

    char buf[64] = {0};
    snprintf(buf, sizeof(buf), "topic response --- %d", count);
    CMqttClientImpl::instance()->publishMessage("mqtt_example1", std::string(buf));
    count += 1;
    //看 MQTTAsync_messageArrived 的注释,这里返回1,否则再接收消息时会有问题
    return 1;
}

此时程序和客户端mqtt fx配合使用正常。

4)问题

在使用过程中遇到了两个问题:

a) mqtt fx客户端发布消息后,程序接收正常,但在客户端修改消息内容再发布,程序接收到的消息跟第一次接收的消息一样。原因为没有进行消息和主题的释放,即在接收消息回调里需要添加

 //每次调用完需要释放,否则接收的消息一直是第一次的
 MQTTAsync_freeMessage(&message);
 MQTTAsync_free(topicName);

b) 接收消息异常,第一次接收到的消息正常,但之后接收的消息都是异常的,打印出来如下:

主题打印出现乱码,再打印主题长度时居然出现负数:

后查看回调函数说明后才知回调函数需要return 1,1表示处理成功,一开始我是return 0了,因为大部分return 0表示没有问题,结果这个回调却不是,大意了。

完整源码可在 我的github 里的mqtt取得,源码只是简单的示例,欢迎下载、修改。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值