当前位置: 首页 > news >正文

C++开发基础之使用librabbitmq库实现RabbitMQ消息队列通信

在这里插入图片描述

1. 前言

RabbitMQ是一个流行的开源消息队列系统,支持多种消息协议,广泛用于构建分布式系统和微服务架构。可以在不同应用程序之间实现异步消息传递。在本文中,我们将熟悉如何使用C++与RabbitMQ进行消息通信。

2. 准备工作

在 Windows 平台上通过 vcpkg 安装 librabbitmq,并在 C++ 中使用该库实现 RabbitMQ 消息的发布和接收。librabbitmq 是官方的 C 客户端库,支持与 RabbitMQ 服务器的通信。在这里插入图片描述

2.1 安装 vcpkg

如果还没有安装 vcpkg,请按照以下步骤安装:

  1. 克隆 vcpkg 仓库:

    git clone https://github.com/microsoft/vcpkg.git
    
  2. 进入 vcpkg 目录并运行安装脚本:

    cd vcpkg
    .\bootstrap-vcpkg.bat
    
  3. 使用 vcpkg 安装 RabbitMQ C 库(librabbitmq):

    vcpkg install librabbitmq
    

在这里插入图片描述

安装完成后,将 vcpkg 集成到项目中:

vcpkg integrate install

这样,librabbitmq 库会被自动链接到 Visual Studio 中的 C++ 项目。
在这里插入图片描述

2.2 配置 Visual Studio 项目

在 Visual Studio 中创建新的 C++ 项目,确保项目中包含了 vcpkg 的安装路径。vcpkg 会自动配置项目,使其能够找到并链接到 librabbitmq 库。并且链接器附加依赖项添加rabbitmq.4.lib便于程序查找rabbitmq.4.dll库引用。
在这里插入图片描述

3. 实现消息发送和接收程序

我们将编写两个程序,一个用于发送消息,一个用于接收消息。这些程序将演示如何使用 librabbitmq 库连接到 RabbitMQ 服务器、声明交换机、绑定队列并发送或接收消息。

3.1 启动rabbitmq Server

在这里插入图片描述

3.2 发送消息的程序(Producer)

以下是消息发送者的完整代码,它会循环发送多条消息到指定的 RabbitMQ 交换机和队列。

#include <iostream>
#include <string>
#include <amqp.h>
#include <amqp_tcp_socket.h>
#include <thread>
#include <chrono>// 用于处理 AMQP 错误并输出错误信息
void die_on_error(amqp_rpc_reply_t x, const char* context) {if (x.reply_type != AMQP_RESPONSE_NORMAL) {std::cerr << "Error in " << context << ": "<< amqp_error_string2(x.library_error) << std::endl;exit(1);}
}int main() {const std::string hostname = "localhost";  // RabbitMQ 服务器地址const int port = 5672;  // RabbitMQ 默认端口const std::string exchange = "example_exchange";  // 交换机名称const std::string routing_key = "example_key";  // 路由键,用于绑定队列// 初始化连接amqp_connection_state_t conn = amqp_new_connection();amqp_socket_t* socket = amqp_tcp_socket_new(conn);if (!socket) {std::cerr << "Creating TCP socket failed" << std::endl;return 1;}// 打开 TCP 连接int status = amqp_socket_open(socket, hostname.c_str(), port);if (status) {std::cerr << "Opening TCP socket failed" << std::endl;return 1;}// 登录 RabbitMQdie_on_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"), "Logging in");amqp_channel_open(conn, 1);  // 打开信道die_on_error(amqp_get_rpc_reply(conn), "Opening channel");// 声明交换机(类型为 direct)amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange.c_str()), amqp_cstring_bytes("direct"),0, 0, 0, 0, amqp_empty_table);die_on_error(amqp_get_rpc_reply(conn), "Declaring exchange");// 循环发送多条消息for (int i = 1; i <= 1000; ++i) {  // 发送 1000 条消息std::string message = "Hello, RabbitMQ! Message number: " + std::to_string(i);amqp_bytes_t message_bytes = amqp_cstring_bytes(message.c_str());// 设置消息属性amqp_basic_properties_t props;props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;props.content_type = amqp_cstring_bytes("text/plain");props.delivery_mode = 2;  // 持久化模式// 发送消息到交换机int result = amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange.c_str()), amqp_cstring_bytes(routing_key.c_str()),0, 0, &props, message_bytes);if (result < 0) {std::cerr << "Error publishing message " << i << std::endl;} else {std::cout << "Message " << i << " published: " << message << std::endl;}// 每次发送后等待 1 秒std::this_thread::sleep_for(std::chrono::seconds(1));}// 清理连接amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS);amqp_connection_close(conn, AMQP_REPLY_SUCCESS);amqp_destroy_connection(conn);return 0;
}

执行结果
在这里插入图片描述

3.3 接收消息的程序(Consumer)

以下是接收消息的完整代码,使用 amqp_consume_message 接收并打印消息内容。

#include <iostream>
#include <string>
#include <amqp.h>
#include <amqp_tcp_socket.h>// 错误处理函数,用于输出错误信息
void die_on_error(amqp_rpc_reply_t x, const char* context) {if (x.reply_type != AMQP_RESPONSE_NORMAL) {std::cerr << "Error in " << context << ": "<< amqp_error_string2(x.library_error) << std::endl;exit(1);}
}int main() {const std::string hostname = "localhost";  // RabbitMQ 服务器地址const int port = 5672;  // 端口const std::string queue = "example_queue";  // 队列名称const std::string exchange = "example_exchange";  // 交换机名称const std::string routing_key = "example_key";  // 路由键// 初始化连接amqp_connection_state_t conn = amqp_new_connection();amqp_socket_t* socket = amqp_tcp_socket_new(conn);if (!socket) {std::cerr << "Creating TCP socket failed" << std::endl;return 1;}// 打开 TCP 连接int status = amqp_socket_open(socket, hostname.c_str(), port);if (status) {std::cerr << "Opening TCP socket failed" << std::endl;return 1;}// 登录 RabbitMQdie_on_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"), "Logging in");amqp_channel_open(conn, 1);die_on_error(amqp_get_rpc_reply(conn), "Opening channel");// 声明交换机和队列,并绑定队列到交换机amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange.c_str()), amqp_cstring_bytes("direct"),0, 0, 0, 0, amqp_empty_table);die_on_error(amqp_get_rpc_reply(conn), "Declaring exchange");amqp_queue_declare_ok_t* q = amqp_queue_declare(conn, 1, amqp_cstring_bytes(queue.c_str()), 0, 0, 0, 1, amqp_empty_table);die_on_error(amqp_get_rpc_reply(conn), "Declaring queue");amqp_queue_bind(conn, 1, amqp_cstring_bytes(queue.c_str()), amqp_cstring_bytes(exchange.c_str()), amqp_cstring_bytes(routing_key.c_str()), amqp_empty_table);die_on_error(amqp_get_rpc_reply(conn), "Binding queue");// 开始消费消息amqp_basic_consume(conn, 1, amqp_cstring_bytes(queue.c_str()), amqp_empty_bytes, 0, 1, 0, amqp_empty_table);die_on_error(amqp_get_rpc_reply(conn), "Consuming");while (true) {amqp_rpc_reply_t res;amqp_envelope_t envelope;// 释放资源amqp_maybe_release_buffers(conn);res = amqp_consume_message(conn, &envelope, NULL, 0);// 检查并打印接收到的消息if (res.reply_type == AMQP_RESPONSE_NORMAL) {std::cout << "Received: " << std::string((char*)envelope.message.body.bytes, envelope.message.body.len) << std::endl;amqp_destroy_envelope(&envelope);} else {std::cerr << "Error consuming message" << std::endl;break;}}

执行结果
在这里插入图片描述
可以查看RabbitMQ的webUI,了解消息的投递和消费情况
在这里插入图片描述

4. 总结

我们已完成了在 Windows 平台上通过 vcpkg 安装 librabbitmq 并用 C++ 实现 RabbitMQ 消息发送和接收的完整教程。

相关文章:

C++开发基础之使用librabbitmq库实现RabbitMQ消息队列通信

1. 前言 RabbitMQ是一个流行的开源消息队列系统&#xff0c;支持多种消息协议&#xff0c;广泛用于构建分布式系统和微服务架构。可以在不同应用程序之间实现异步消息传递。在本文中&#xff0c;我们将熟悉如何使用C与RabbitMQ进行消息通信。 2. 准备工作 在 Windows 平台上…...

头歌网络安全(11.12)

头歌禁止复制解决 必须先下篡改猴&#xff01;&#xff01;&#xff01;&#xff01; 头歌复制助手 Educoder Copy Helperhttps://scriptcat.org/zh-CN/script-show-page/1860 Java生成验证码 第1关&#xff1a;使用Servlet生成验证码 任务描述 本关任务&#xff1a;使用se…...

洛谷 P1725 琪露诺(线段树优化dp)

题目链接 https://www.luogu.com.cn/problem/P1725 思路 我们令 d p [ i ] dp[i] dp[i]表示琪露诺移动到第 i i i个格子时能够获得的最大冰冻指数。 显然&#xff0c;状态转移方程为&#xff1a; d p [ i ] m a x ( d p [ i ] , d p [ k ] a [ i ] ) dp[i] max(dp[i],dp…...

【LeetCode】【算法】19. 删除链表的倒数第N个结点

LeetCode 19. 删除链表的倒数第N个结点 题目描述 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 思路 思路&#xff1a;快慢指针&#xff0c;快指针先移动n步&#xff0c;快慢指针再同时移动直到快指针到达链表末尾&#xff0c;此…...

Python爬虫 | 爬取豆瓣电影Top250的数据

简单记录一下&#xff0c;实现爬取豆瓣电影Top 250的数据。 这里我使用requests库来发送HTTP请求&#xff0c;以及BeautifulSoup库来解析HTML页面。 1.安装requests和BeautifulSoup库。 如果没有安装&#xff0c;可以通过以下命令安装&#xff1a; pip install requests bea…...

mac 中python 安装mysqlclient 出现 ld: library ‘ssl‘ not found错误

1. 出现报错 2. 获取openssl位置 brew info openssl 3. 配置环境变量&#xff08;我的是在~/.bash.profile&#xff09; export LDFLAGS"-L/opt/homebrew/Cellar/openssl3/3.4.0/lib" export CPPFLAGS"-I/opt/homebrew/Cellar/openssl3/…...

完全清除:苹果手机照片怎么彻底删除

在使用iPhone的过程中&#xff0c;由于拍摄积累的照片往往会占用大量存储空间。有时候&#xff0c;我们需要彻底删除这些照片以释放空间或保护隐私。苹果手机照片怎么彻底删除&#xff1f;在此&#xff0c;本文将与你分享一些实用的技巧。 彻底删除的重要性 彻底删除照片不仅涉…...

高德地图多个图片组成标点(自定义点标记内容)

图标的实现自定义点标记内容...

02-1_MVCC版本链清理

MVCC-版本链清理 文章目录 MVCC-版本链清理简介依赖机制Purge 操作的触发时机版本链清理的详细过程示例操作流程延迟清理配置和监控总结 简介 MySQL 中的 MVCC 机制通过版本链来管理数据的多版本存储&#xff0c;以支持高并发的读写操作。然而&#xff0c;随着事务的进行&…...

探索Python视频处理的瑞士军刀:ffmpeg-python库

文章目录 **探索Python视频处理的瑞士军刀&#xff1a;ffmpeg-python库**第一部分&#xff1a;背景介绍第二部分&#xff1a;ffmpeg-python库是什么&#xff1f;第三部分&#xff1a;如何安装ffmpeg-python库&#xff1f;第四部分&#xff1a;简单库函数使用方法1. 视频转码2. …...

进程间通信 - 通道

进程间通信 - 通道 什么是管道&#xff1f; 进程间的通信方式有五种&#xff0c;分别为:管道、信号量、共享内存、消息队列和套接字。 管道:本质上就是一个文件&#xff0c;前面的进程以写方式打开文件&#xff0c;后面的进程以读方式打开。这样前面写完后面读&#xff0c;于…...

华为数通HCIA系列第5次考试-【2024-46周-周一】

文章目录 1、子网掩码有什么作用&#xff0c;和IP地址是什么关系&#xff0c;利用子网掩码可以获取哪些信息&#xff1f;2、已知一个IP地址是192.168.1.1&#xff0c;子网掩码是255.255.255.0&#xff0c;求其网络地址3、已知某主机的IP地址是192.168.100.200&#xff0c;子网掩…...

【Linux】如何通过终端命令查看当前可用网络 WIFI + 设置已配置网络的连接优先级 + 连接/断连网络

【Linux】通过命令行&#xff0c;查看当前可用网络 WIFI 设置已配置网络的连接优先级 连接网络 列出所有可连接网络 nmcli device wifi list这个命令会列出所有可连接 wifi&#xff0c;*表示当前连接。 IN-USE BSSID SSID MODE CHAN …...

华为路由策略配置

一、AS_Path过滤 要求&#xff1a; AR1与AR2、AR2与AR3之间建立EBGP连接 AS10的设备和AS30的设备无法相互通信 1.启动设备 2.配置IP地址 3.配置路由器的EBGP对等体连接&#xff0c;引入直连路由 [AR1]bgp 10 [AR1-bgp]router-id 1.1.1.1 [AR1-bgp]peer 200.1.2.2 as-nu…...

Debezium日常分享系列之:异步 Debezium 嵌入式引擎

Debezium日常分享系列之&#xff1a;异步 Debezium 嵌入式引擎 动机目标非目标保留Kafka Connect模型计划的更改线程池并行运行源任务存储偏移量并发处理CDC事件禁用CDC事件的完全排序自定义记录处理器并行处理记录的选项存储偏移量引擎状态和生命周期防止资源泄漏异常处理退出…...

leetcode206. Reverse Linked List

Given the head of a singly linked list, reverse the list, and return the reversed list. 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 思路一:双指针 class Solu…...

【MATLAB源码-第291期】基于matlab的AMI编码解码系统仿真,输出各个节点波形。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 AMI&#xff08;Alternate Mark Inversion&#xff0c;交替极性反转&#xff09;是一种广泛使用的编码方法&#xff0c;尤其是在通信系统中&#xff0c;用于传输二进制数据。AMI编码的特点是在传输过程中&#xff0c;对于0信…...

springboot苍穹外卖实战:十一:复盘总结

近期在整理草稿区&#xff0c;故放出此贴。 server模块需要导入对common模块的依赖 <dependency><groupId>org.example</groupId><artifactId>sky-common</artifactId><version>1.0-SNAPSHOT</version></dependency>我现在有个…...

基于Python的药房管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

chat2db数据库图形化工具

数据库图形化工具 DataGrip&#xff1a;由 JetBrains 公司开发&#xff0c;是开发者中广为人知的数据库管理工具&#xff0c;功能强大且支持多种数据库。DBeaver&#xff1a;一款开源的数据库管理工具&#xff0c;虽然相对 DataGrip 知名度稍低&#xff0c;但在开发者社区中也…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...

开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 罗克韦尔PLC&#xff0c;但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控&#xff0c;引入了开疆智能Etherne…...

【向量库】Weaviate概述与架构解析

文章目录 一、什么是weaviate二、High-Level Architecture1. Core Components2. Storage Layer3. 组件交互流程 三、核心组件1. API Layer2. Schema Management3. Vector Indexing3.1. 查询原理3.2. 左侧&#xff1a;Search Process&#xff08;搜索流程&#xff09;3.3. 右侧&…...