Linux C 实现rocketMQ生产者和消费者

546 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、环境:

PC操作系统:CentOS Linux release 7.9.2009 (Core) gcc 版本:4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) rocketmq-client-cpp版本:2.2.0

以下demo基于 rocketmq-client-cpp-2.2.0 实现,编译可参考 Linux 下 rocketmq-client-cpp 2.2.0 编译

二、代码:

我这里把生产者和消费者的代码又稍微封装了一下,形成一个可以方便调用的工具模块。 只是简单示范一下函数调用。

1、生产者

tool_product.c

/**************************************************************************************************
**  文件名称:tool_product.c
**  文件描述:rocketMQ生产者工具
**  ===============================================================================================
**  创建信息:| 2022-4-12 | hrx | 创建本模块
**  ===============================================================================================
**************************************************************************************************/
#include <stdio.h>
#include "CCommon.h"
#include "CMessage.h"
#include "CProducer.h"
#include "CSendResult.h"
#include <memory.h>

#include "tool_product.h"

static CProducer *s_producer = NULL;                                                               /* 生产者结构 */

/**************************************************************************************************
**  函数名称:tool_mq_product_packmsg
**  功能描述:消息打包
**  输入参数:*topic:消息的主题
**           *tag:消息的tag
**           *key:消息的key
**           *msgstr:消息内容
**  输出参数:无
**  返回参数:消息结构体(用完需要被释放)
**************************************************************************************************/
CMessage *tool_mq_product_create_msg(char *topic, char *tag, char *key, char *msgstr)
{
    CMessage *msg;                                                                                 /* 消息结构体 */
    
    if (NULL == topic || NULL == tag || NULL == key || NULL == msgstr) {
        return NULL;
    }
    
    msg = CreateMessage(topic);
    SetMessageTags(msg, tag);
    SetMessageKeys(msg, key);
    SetMessageBody(msg, msgstr);

    return msg;
}

/**************************************************************************************************
**  函数名称:tool_mq_product_destory_msg
**  功能描述:销毁消息
**  输入参数:*msg:消息结构体
**  输出参数:无
**  返回参数:无
**************************************************************************************************/
void tool_mq_product_destory_msg(CMessage *msg)
{
    if (msg) {
        DestroyMessage(msg);
    }
}

/**************************************************************************************************
**  函数名称:tool_mq_product_sendmsg
**  功能描述:rocketMQ消息队列客户端发送消息
**  输入参数:*msgstr:消息内容
**            msglen:消息内容长度
**  输出参数:无
**  返回参数:成功:0, 失败-1
**************************************************************************************************/
int tool_mq_product_sendmsg(CMessage *msg)
{
    CSendResult result;                                                                            /* 发送结果 */

    if (NULL == msg) {
        return -1;
    }

    SendMessageSync(s_producer, msg, &result);
    
    printf("try to send  = %s\n", GetOriginMessageBody(msg));

    switch (result.sendStatus) {
        case E_SEND_OK:                                                                          /* 发送成功 */
            printf("send OK = %s\n", GetOriginMessageBody(msg));
            return 0;

        case E_SEND_FLUSH_DISK_TIMEOUT:                                                          /* 刷新超时时间 */
            printf("E_SEND_FLUSH_DISK_TIMEOUT\n");
            return -1;
        case E_SEND_FLUSH_SLAVE_TIMEOUT:                                                         /* 刷新从节点超时 */
            printf("E_SEND_FLUSH_SLAVE_TIMEOUT\n");
            return -1;
        case E_SEND_SLAVE_NOT_AVAILABLE:                                                         /* 从机不可用 */
            printf("E_SEND_SLAVE_NOT_AVAILABLE\n");
            return -1;
        default:
            printf("not should be here\n");
            return -1;
    }

    DestroyMessage(msg);

    return 0;
}

/**************************************************************************************************
**  函数名称:tool_mq_product_init
**  功能描述:rocketMQ消息队列客户端初始化
**  输入参数:*serverAddr:服务端的IP、端口, 格式xxx.xxx.xxx.xxx:yyyy
**  输出参数:无
**  返回参数:成功:0, 失败:-1
**************************************************************************************************/
int tool_mq_product_init(char *serverAddr)
{
    if (s_producer) {
        ShutdownProducer(s_producer);
        DestroyProducer(s_producer);
    }
    
    s_producer = CreateProducer("unimrcp_producer_1");
    SetProducerNameServerAddress(s_producer, serverAddr);
    StartProducer(s_producer);
    return 0;
}

/**************************************************************************************************
**  函数名称:tool_mq_product_deinit
**  功能描述:rocketMQ消息队列客户端反初始化
**  输入参数:无
**  输出参数:无
**  返回参数:成功:0, 失败:-1
**************************************************************************************************/
int tool_mq_product_deinit()
{
    if (s_producer) {
        ShutdownProducer(s_producer);
        DestroyProducer(s_producer);
    }

    return 0;
}

tool_product.h

/**************************************************************************************************
**  文件名称:tool_product.h
**  文件描述:rocketMQ生产者工具
**  ===============================================================================================
**  创建信息:| 2022-4-12 | hrx | 创建本模块
**  ===============================================================================================
**************************************************************************************************/
#ifndef TOOL_PRODUCT_H
#define TOOL_PRODUCT_H

#define DEFAULT_SERVER_ADDRESS          "xxx.xxx.xxx.xxx:9876"                                       /* 默认服务器IP和端口号 */

#include "CMessage.h"

/* 消息打包 */
CMessage *tool_mq_product_create_msg(char *topic, char *tag, char *key, char *msgstr);

/* 销毁消息 */
void tool_mq_product_destory_msg(CMessage *msg);

/* rocketMQ消息队列客户端发送消息 */
int tool_mq_product_sendmsg(CMessage *msg);

/* rocketMQ消息队列客户端初始化 */
int tool_mq_product_init(char *serverAddr);

/* rocketMQ消息队列客户端反初始化 */
int tool_mq_product_deinit();

#endif

main.c

/**************************************************************************************************
**  文件名称:main.c
**  文件描述:MQ 生产者测试程序
**  ===============================================================================================
**  创建信息:| 2022-4-12 | hrx | 创建本模块
**  ===============================================================================================
**************************************************************************************************/
#include <stdio.h>
#include <unistd.h>

#include "tool_product.h"

int main(int argc, char *argv[])
{
    CMessage *cmsg;

    tool_mq_product_init("218.85.131.35:9876");

    while (1) {
        cmsg = tool_mq_product_create_msg("rocketmq_topic", "tag - 1", "key - 1", "msg - 1");
        tool_mq_product_sendmsg(cmsg);
        tool_mq_product_destory_msg(cmsg);
        sleep(10);
    }
    return 0;
}

2、消费者

tool_consumer.c

/**************************************************************************************************
**  文件名称:tool_consumer.c
**  文件描述:rocketMQ消费者工具
**  ===============================================================================================
**  创建信息:| 2022-4-12 | hrx | 创建本模块
**  ===============================================================================================
**************************************************************************************************/
#include <stdio.h>
#include "CCommon.h"
#include "CMessageExt.h"
#include "CPushConsumer.h"

#include <memory.h>

#include "tool_consumer.h"

static CPushConsumer *s_consumer = NULL;                                                           /* 消费者结构 */

/**************************************************************************************************
**  函数名称:deal_consume_msg
**  功能描述:获取订阅主题的消息
**  输入参数:无
**  输出参数:无
**  返回参数:无
**************************************************************************************************/
int deal_consume_msg(struct CPushConsumer* consumer, CMessageExt* msgExt) {
    const char *topic;
    const char *tag;
    const char *key;
    const char *body;
    
    topic = GetMessageTopic(msgExt);
    tag   = GetMessageTags(msgExt);
    key   = GetMessageKeys(msgExt);
    body  = GetMessageBody(msgExt);

    printf("consume, tp:%s, tg:%s, ky:%s, bd:%s\n", topic, tag, key, body);
    
    return E_CONSUME_SUCCESS;
}

/**************************************************************************************************
**  函数名称:tool_mq_consumer_init
**  功能描述:rocketMQ消息队列客户端初始化
**  输入参数:*serverAddr:服务端的IP、端口, 格式xxx.xxx.xxx.xxx:yyyy
**  输出参数:无
**  返回参数:成功:0, 失败:-1
**************************************************************************************************/
int tool_mq_consumer_init(char *serverAddr)
{
    s_consumer = CreatePushConsumer("unimrcp_consumer_1");
    SetPushConsumerNameServerAddress(s_consumer, serverAddr);
    Subscribe(s_consumer, "rocketmq_topic", "*");
    RegisterMessageCallback(s_consumer, deal_consume_msg);
    StartPushConsumer(s_consumer);
    
    return 0;
}

/**************************************************************************************************
**  函数名称:tool_mq_consumerdeinit
**  功能描述:rocketMQ消息队列客户端反初始化
**  输入参数:无
**  输出参数:无
**  返回参数:成功:0, 失败:-1
**************************************************************************************************/
int tool_mq_consumerdeinit()
{
    if (s_consumer) {
        ShutdownPushConsumer(s_consumer);
        DestroyPushConsumer(s_consumer);
    } 

    return 0;
}

tool_consumer.h

/**************************************************************************************************
**  文件名称:tool_consumer.h
**  文件描述:rocketMQ消费者工具
**  ===============================================================================================
**  创建信息:| 2022-4-12 | hrx | 创建本模块
**  ===============================================================================================
**************************************************************************************************/
#ifndef TOOL_CONSUMER_H
#define TOOL_CONSUMER_H

#include "CMessage.h"

/* rocketMQ消息队列客户端初始化 */
int tool_mq_consumer_init(char *serverAddr);

/* rocketMQ消息队列客户端反初始化 */
int tool_mq_consumer_deinit();

#endif

main.c

/**************************************************************************************************
**  文件名称:main.c
**  文件描述:MQ 消费者测试程序
**  ===============================================================================================
**  创建信息:| 2022-4-12 | hrx | 创建本模块
**  ===============================================================================================
**************************************************************************************************/
#include <stdio.h>
#include <unistd.h>

#include "tool_consumer.h"

int main(int argc, char *argv[])
{

    tool_mq_consumer_init("218.85.131.35:9876");

    while (1) {
        sleep(10);
    }
    return 0;
}

三、编译

编译时需要引用到 rocketmq-client-app工程编译出来的动态、静态库。 在这里插入图片描述

测试

1、生产者

在这里插入图片描述

2、消费者

在这里插入图片描述