使用C++开发基于RabbitMQ消息中间件的应用

使用C++开发基于RabbitMQ消息中间件的应用

一、概述

消息中间件在分布式系统中完成消息的发送和接收的功能,可以提供高效可靠的消息传递机制进行平台无关的数据交换。消息队列已经逐渐成为企业IT系统内部通信的核心手段。RabbitMQ作为消息队列中间件,在产品开发中被广泛使用。

二、业务场景

下面以一个需要解决的业务场景为例,对如何使用C++进行消息队列中间件的集成开发进行演示。业务场景如下:

某化工企业需要对某重要的液体化工原料进行液位监控,现场通过液位控制器获取液位传感器捕获的液位信息,控制器将液位信息上传至中心端进行管理。

为了使现场控制器系统和中心管理端系统有效集成,数据交换可以采用消息中间件。整体设计如下:

在这里插入图片描述

如上图所示,现场控制器负责将液位传感器信号转换为数字信号,然后将数据传送至数据中心的消息队列服务器,业务应用服务器从消息队列服务器获取信息,最终转化为业务数据进行处理和展示。

此示例主要以现场控制器发送数据到消息队列服务器为例,进行构建。

现场控制器一般由小型工控机组成,硬件架构可以是X86或ARM,操作系统一般为Windows或Linux。消息队列服务器采用RabbitMQ作为中间件。下面的示例现场控制器采用Windows10_X64结构,控制器数据采集程序基于MSVC进行编译。

三、准备工作

  1. 与RabbitMQ服务器进行通信,需要一个客户端,官方推荐的客户端程序是rabbitmq-c,这是一个C编写的客户端通信库,如果使用C++,需要对其进行封装。rabbitmq-c的作者提供了一个C++封装的类库,我们可以采用该类库作为开发类库。该类库编译依赖rabbitmq-c和boost,故首先需要将boost和rabbitmq-c相关类库编译好。
  2. 编译boost库

​ 下载最新版的boost库(1.86.0),解压后,执行bootstrap.bat,生成b2.exe文件,在命令行终端执行b2.exe,执行结束后,boost开发库便安装完成。(boost库头文件目录就是解压目录,库文件为stage/lib目录)

  1. 编译rabbitmq-c库

​ 下载解压后,从命令行进入刚刚解压的目录,在此目录中,执行以下命令:

mkdir build
cd build
cmake ..
cmake --build . --config release

​ 执行完成后,将在build目录下的librabbitmq\Release文件夹中编译出如下类库

在这里插入图片描述

​ 其中librabbitmq.4.lib为静态库,rabbitmq.4.lib为动态库

还需要将build目录下的include\rabbitmq-c目录下的export.h文件拷贝至解压目录下的include\rabbitmq-c目录中

  1. 编译SimpleAmqpClient库

    下载解压后,在解压目录中,打开CMakeLists.txt文件,找到地52行,将Boost_Dynamic_Linking_ENABLED选项设置为OFF

    在这里插入图片描述

    找到64行,在find_package命令之上增加Boost的CMake配置(我的boost开发库安装在d:\workspace32下)

    在这里插入图片描述

    找到70行,在find_package命令之上增加rabbitmq-c库的相关配置

    完成以上配置后,保存文件

    打开命令行,进入SimpleAmqpClient解压目录,执行以下命令

    mkdir build
    cd build
    cmake ..
    cmake --build . --config release
    

    执行完成后,在build/Release目录中,将生成以下库文件

四、应用开发

  1. 打开Visual Studio,创建CMake项目

在这里插入图片描述

  1. 创建rmq_demo工程,在该工程中,创建以下目录:

在这里插入图片描述

​ 其中include目录放置SimpleAmqpClient的头文件,lib目录放置编译好的SimpleAmqpClient.7.lib库文件,src目录为编写的代码。

  1. 编写rmq_sender.cpp,向mq发送消息,内容如下:
#include <SimpleAmqpClient/SimpleAmqpClient.h>
#include <iostream>
#include <chrono>
#include <thread>

static unsigned int counter = 1;

int main() {
	try{
		AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create("x.x.x.x", 5672, "username", "password", "/");
		std::string q_name = "plain_txt";
		channel->DeclareQueue(q_name, false, true, false, false);
		std::string send_msg = "{\"course\":\"c++\", \"level\": 3 }";
		AmqpClient::BasicMessage::ptr_t msg_ptr = AmqpClient::BasicMessage::Create(send_msg);
		std::cout << "Message Generated. Ready to send. Content [ " << send_msg << " ]\n";
		while (true) {
			channel->BasicPublish("", q_name, msg_ptr);
			std::cout << counter++ << " >===== Sent " << send_msg << std::endl;
			std::this_thread::sleep_for(std::chrono::milliseconds(300));
		}
	}
	catch (std::exception& e) {
		std::cerr << e.what() << std::endl;
		return -1;
	}
	return 0;
}
  1. 编写CMakeLists.txt编译脚本,内容如下:

cmake_minimum_required (VERSION 3.8)

project ("simple_mq_sender")

set(CMAKE_CXX_STANDARD 17)

if(NOT DEFINED BIN_DIR)
    set(BIN_DIR ${PROJECT_SOURCE_DIR}/bin/${TARGET})
endif()

aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)

include_directories(${PROJECT_SOURCE_DIR}/include $ENV{include})

add_executable(mq_sender ${SRC})

target_link_libraries(mq_sender ${PROJECT_SOURCE_DIR}/lib/SimpleAmqpClient.7.lib)

该编译过程需要读取Boost开发库的头文件,需要在cmakelists.txt文件中将boost头文件目录通过include_directories指令进行配置。以上示例中通过include环境变量将工程编译的必要头文件都包含在其中。

  1. 编译

​ 可以通过命令行进行编译,也可以通过命令行命令进行编译

  1. 运行

​ 编译成功后,将所需动态运行库拷贝至和编译的可执行文件同一目录下,执行即可。

以上是消息发送程序,消息接收程序和以上构建过程基本相同,以下是消息接收程序的示例:

  1. mq_receiver.cpp
#include <SimpleAmqpClient/SimpleAmqpClient.h>
#include <iostream>
#include <chrono>
#include <thread>
static unsigned int counter = 1;

int main() {
    try {
        AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create("x.x.x.x", 5672, "username", "password", "/");
        std::string q_name = "plain_txt";
        channel->DeclareQueue(q_name, false, true, false, false);

        std::string consumer_tag = channel->BasicConsume(q_name);
        std::cout << " [*] Waiting for message... To exit press Ctrl+c" << std::endl;

        while (true) {
            AmqpClient::Envelope::ptr_t envolope = channel->BasicConsumeMessage(consumer_tag);
            std::string message_body = envolope->Message()->Body();
            std::cout << counter++ << " >==== Received " << message_body << std::endl;
            std::this_thread::sleep_for(std::chrono::milliseconds(20));
        }
    }
    catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
        return -1;
    }
    return 0;
}
  1. CMakeLists.txt
cmake_minimum_required (VERSION 3.8)

project ("simple_mq_receiver")

set(CMAKE_CXX_STANDARD 17)
if(NOT DEFINED BIN_DIR)
    set(BIN_DIR ${PROJECT_SOURCE_DIR}/bin/${TARGET})
endif()

aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
include_directories(${PROJECT_SOURCE_DIR}/include $ENV{include})
add_executable(mq_receiver "src/rmqReceiver.cpp")
target_link_libraries(mq_receiver ${PROJECT_SOURCE_DIR}/lib/SimpleAmqpClient.7.lib)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值