MQTT协议软件包moquitto C语言编程使用

mosquitto-2.0.9安装:https://blog.csdn.net/qq_36413982/article/details/115184473
mosquitto的API文档:/home/roger/src/mqtt/mosquitto/lib/mosquitto.h
https://mosquitto.org/api/files/mosquitto-h.html#mosquitto_loop_forever

mosquitto的API简单易用,基于回调函数编程。

订阅者mosquitto_sub.c:

#include "mosquitto.h"
#include "stdio.h"
#include "string.h"
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

#define ARR_SIZE(a)  (sizeof(a)/sizeof(a[0]))

#define MQTT_PORT   1883

struct mosquitto *mosq = NULL;

static const char *topic[] = {
    
    
    "led",
    "fan",
    "curtain",
};

static int mosquitoto_subscribe_topic(const char *topic, int mid, int qos)
{
    
    
    return mosquitto_subscribe(mosq, &mid, topic, qos);
}

static void mosq_on_connect_callback(struct mosquitto *mosq, void *obj, int mid)
{
    
    
    int ret = 0;

    for (int i = 0; i < ARR_SIZE(topic); i++)
    {
    
    
        if ((ret = mosquitoto_subscribe_topic(topic[i], i, 2)) == MOSQ_ERR_SUCCESS)           //订阅主题
        {
    
    
            printf("subscribe success\n");
        }
        else
        {
    
    
            fprintf(stderr, "subscribe failed %d\n", ret);
        }
    }

    if ((ret = mosquitoto_subscribe_topic("aaa", 0, 2)) == MOSQ_ERR_SUCCESS)           //订阅主题
    {
    
    
        printf("subscribe success\n");
    }
    else
    {
    
    
        fprintf(stderr, "subscribe failed %d\n", ret);
    }
   
}

static void mosq_on_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
    
    

}

static void mosq_on_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
    
    

}

void mosq_on_message_get_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
{
    
    
    if (message->payloadlen > 0)
    {
    
    
        printf("topic : %s, message : %s\r\n", message->topic, (char *)message->payload);
    }
}

static void mosquitto_mqtt_init(char *host, int port, int keepalive)
{
    
    
    mosquitto_lib_init();     //初始化mosquitto库

    mosq = mosquitto_new(NULL, true, NULL);     //创建一个mosquitto实例

    if (mosq == NULL)
    {
    
    
        mosquitto_lib_cleanup();
        printf("create mosquitto obj failed\r\n");   
        exit(1);
    }

    mosquitto_connect_callback_set(mosq, mosq_on_connect_callback);       //设置连接成功回到函数
    mosquitto_publish_callback_set(mosq, mosq_on_publish_callback);       //设置发布成功回调函数
    mosquitto_subscribe_callback_set(mosq, mosq_on_subscribe_callback);   //设置订阅请求成功回调函数
    mosquitto_message_callback_set(mosq, mosq_on_message_get_callback);   //设置消息接收成功回调

    int retries = 0;
    //return val MOSQ_ERR_SUCCESS
    while (mosquitto_connect(mosq, host, port, keepalive) != MOSQ_ERR_SUCCESS && retries < 5)   //如果连接失败,尝试重复连接5次
    {
    
    
        retries++;
    }

    if (retries >= 5)
    {
    
    
        printf("connect mqtt broker failed\n");
        mosquitto_destroy(mosq);    //连接失败销毁
        mosquitto_lib_cleanup();
        exit(1);
    }
    printf("connect mqtt broker\r\n");
}


int main(int argc, char **argv)
{
    
    
    if (argc != 2)
    {
    
    
        printf("Usage: %s <host_ip>\r\n", argv[0]);
        exit(1);
    }

    char *host = argv[1];
    int port = MQTT_PORT;
    int keepalive = 30;

    mosquitto_mqtt_init(host, port, keepalive);
   
    if (mosquitto_loop_start(mosq) != MOSQ_ERR_SUCCESS)
    {
    
    
        printf("failed to Call this once to start a new thread to process network traffic\n");
        mosquitto_destroy(mosq);      //连接失败销毁
        mosquitto_lib_cleanup();
        exit(1);
    }

    while (1)
    {
    
    
        // mosquitto_loop(mosq, -1, 1);
        // printf("subscribe client running\n");
        sleep(2);
    }
 
    mosquitto_destroy(mosq);      //连接失败销毁
    mosquitto_lib_cleanup();
    return 0;
}

发布者mosquitto_pub.c:

#include <mosquitto.h>
#include "stdio.h"
#include "string.h"
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>

#define ARR_SIZE(a)  (sizeof(a)/sizeof(a[0]))

#define MQTT_PORT   1883

enum topic_select {
    
    
    TOPIC_LED = 0,
    TOPIC_FAN,
    TOPIC_CURTAIN,
};
typedef enum topic_select top_sel_t;

struct mosquitto *mosq = NULL;

static const char *topic[] = {
    
    
    "led",
    "fan",
    "curtain",
};

static int mosquitoto_subscribe_topic(const char *topic, int mid, int qos)
{
    
    
    return mosquitto_subscribe(mosq, &mid, topic, qos);
}

static void mosq_on_connect_callback(struct mosquitto *mosq, void *obj, int mid)
{
    
    
    int ret = 0;

    // for (int i = 0; i < ARR_SIZE(topic); i++)
    // {
    
    
    //     if ((ret = mosquitoto_subscribe_topic(topic[i], i, mid)) == MOSQ_ERR_SUCCESS)           //订阅主题
    //     {
    
    
    //         printf("subscribe success\n");
    //     }
    //     else
    //     {
    
    
    //         fprintf(stderr, "subscribe failed %d\n", ret);
    //     }
    // }
    // if ((ret = mosquitoto_subscribe_topic("aaa", 0, 2)) == MOSQ_ERR_SUCCESS)           //订阅主题
    // {
    
    
    //     printf("subscribe success\n");
    // }
    // else
    // {
    
    
    //     fprintf(stderr, "subscribe failed %d\n", ret);
    // }
}

static void mosq_on_publish_callback(struct mosquitto *mosq, void *obj, int mid)
{
    
    
    printf("publish message");
}

static void mosq_on_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
{
    
    
    
}

static void mosquitto_mqtt_init(char *host, int port, int keepalive)
{
    
    
    mosquitto_lib_init();     //初始化mosquitto库

    mosq = mosquitto_new(NULL, true, NULL);     //创建一个mosquitto实例

    if (mosq == NULL)
    {
    
    
        mosquitto_lib_cleanup();
        printf("create mosquitto obj failed\r\n");
        exit(1);
    }

    mosquitto_connect_callback_set(mosq, mosq_on_connect_callback);       //设置连接成功回到函数
    mosquitto_publish_callback_set(mosq, mosq_on_publish_callback);       //设置发布成功回调函数
    mosquitto_subscribe_callback_set(mosq, mosq_on_subscribe_callback);     //设置订阅请求成功回调函数

    int retries = 0;
    //return val MOSQ_ERR_SUCCESS
    while (mosquitto_connect(mosq, host, port, keepalive) != MOSQ_ERR_SUCCESS && retries < 5)   //如果连接失败,尝试重复连接5次
    {
    
    
        retries++;
    }

    if (retries >= 5)
    {
    
    
        printf("connect mqtt broker failed\n");
        mosquitto_destroy(mosq);    //连接失败销毁
        exit(1);
    }
    printf("connect mqtt broker\r\n");
}

int mosquitto_publish_msg(const char * topic, int payloadlen, const void *payload, int mid, int qos)
{
    
    
    return mosquitto_publish(mosq, &mid, topic, payloadlen, payload, qos, false);
}

void publish_msg_handler(top_sel_t select, char *msg)
{
    
    
    int mid;

    switch (select)
    {
    
    
        case TOPIC_LED:
        {
    
    
            mid = TOPIC_LED;
            break;
        }
        case TOPIC_FAN:
        {
    
    
            mid = TOPIC_FAN;
            break;
        }
        case TOPIC_CURTAIN:
        {
    
    
            mid = TOPIC_CURTAIN;
            break;
        }
    }
    printf("select topic :%s\n", topic[mid]);
    printf("send message : %s\n", msg);
    mosquitto_publish_msg(topic[mid], strlen(msg), msg, mid, 2);
}

int main(int argc, char **argv)
{
    
    
    if (argc != 2)
    {
    
    
        printf("Usage: %s <host_ip>\r\n", argv[0]); 
        exit(1);
    }

    char *host = argv[1];
    int port = MQTT_PORT;
    int keepalive = 30;

    mosquitto_mqtt_init(host, port, keepalive);
   
    if (mosquitto_loop_start(mosq) != MOSQ_ERR_SUCCESS)
    {
    
    
        printf("failed to Call this once to start a new thread to process network traffic\n");
        mosquitto_destroy(mosq);      //连接失败销毁
        mosquitto_lib_cleanup();
        exit(1);
    }

    int select  = 0;
    char msg[1024] = {
    
    0};

    sleep(1);
    while (1)
    {
    
    
        printf("please select topic, 0 - led 1 - fan 2 - curtain : ");
        scanf("%d", &select);
        printf("please input message to send:");
        scanf("%s", msg);
        publish_msg_handler((top_sel_t)select, msg);
    }

    return 0;
}

测试:
在这里插入图片描述
MQTT协议的发布者也可以是订阅者,只要发布者也订阅主题就可以实现双向通信,所以MQTT还能用在进程间通信。。。

猜你喜欢

转载自blog.csdn.net/qq_36413982/article/details/115206086