RabbitMQ-C使用开发详解(Windows环境)

基于rabbitmq-c的Rabbitmq C++客户端的实现 基于rabbitmq-c的Rabbitmq C++ Client 仅做记录,后续有问题再修改。 阅读详情
AI摘要

本文详细介绍了Windows环境下RabbitMQ-C的使用开发。首先说明了编译RabbitMQ-c的步骤,包括下载和安装相关代码包与工具,以及使用cmake编译。接着阐述了生产者、交换机、队列和消费者之间的多对多关系等核心原理。最后介绍了开发者相关的接口文件、交换机、队列、生产者和消费者的操作方法。

目录

一、概述

二、编译RabbitMQ-c

三、核心原理

3.1生产者与交换机关系

3.2交换机与队列关系

3.3队列与消费者关系

3.4交换机与交换机的关系

四、开发者

4.1接口文件

4.2交换机

声明交换机

删除交换机

向交换机绑定路由键

从交换机解绑路由键

交换机之间绑定路由键

交换机之间解绑路由键

4.3队列

声明队列

清空队列

删除队列

4.4生产者

4.5消费者

4.5.1订阅

4.5.2拉取


RabbitMQ-C使用开发详解(Windows环境)

 

一、概述

讨论的是windows环境下的使用RabbitMQ-c与RabbitMQ服务端的交互。

 

二、编译RabbitMQ-c

RabbitMq的C/C++客户端有很多,我们选用RabbitMq-c。windows环境下的MFC开发,需要把RabbitMq-c客户端编译成dll。

1.下载和安装

下载rabbitmq-c最新代码包:https://github.com/alanxz/rabbitmq-c

下载cmake最新安装包:https://cmake.org/download/

2.使用cmake编译生成适合自己编译环境的工程

第一步:填写源代码路径

第二步:填写建立后的路径,build的文件夹一般建立在源代码路径里,也可以放在其他位置

第三步:点击配置按钮,在配置里面选择属于自己编译环境的名字

第四步:点击生成按钮,不出现运行失败就说明已经编译成功了

       

特别说明:在编译rabbitmq-c是如果出现如图的错误,可以去掉ENABLE_SSL_SUPPORT括号里的对勾。 

 

在以上生成的工程目录下的librabbitmq\Debug路径下会生成librabbitmq.4.lib、librabbitmq.4.dll两个文件,对应的动态库的导出文件在rabbitmq-c-master\librabbitmq目录下。

 

三、核心原理

3.1生产者与交换机关系

生产者与交换机的关系是多对多的有关系,多个生产者可以给同一个交换机生产消息,同时一个生产者也可以能多个交换机生产消息。

 

3.2交换机与队列关系

交换机与队列的关系是多对多的关系,一个交换机可以给多个队列提供消息,同时多个交换机也可以同时给一个队列提供消息。

 

3.3队列与消费者关系

队列与消费者的关系是多对多的关系,一个队列可以同时被多个消费者消费,同时一个消费者可以同时消费多个队列的消息。

3.4交换机与交换机的关系

交换机与交换机的关系,与交换机与队列的关系是一样的。部份交换机充当队列的角色,从其绑定的交换机上分流数据,然后再把自己角色转换成交换机,然后给绑定在自身上的队列分派消息。

所以交换机之间的关系是多对多,一个上级交换机可以绑定多个下级交换机,一个下级交换机可同时绑定多个上级交换机。

四、开发者

4.1接口文件

总共有4个导出文件:

amqp.h:主要的rabbitmq-c客户端接口都在此文件

amqp_tcp_socket.h:与socket相关的接口

mqp_framing.h:不常用的一些接口

amqp_ssl_socket.h:用户ssl方式加密访问rabbitmq-server

 

生产者生产消息过程:

(1)客户端连接到消息队列服务器,打开一个channel。

(2)客户端声明一个exchange,并设置相关属性。

(3)客户端声明一个queue,并设置相关属性。

(4)客户端使用routing key,在exchange和queue之间建立好绑定关系。

(5)客户端投递消息到exchange。

 

RabbitMQ支持消息的持久化:

也就是数据写在磁盘上,为了数据安全考虑,我想大多数用户都会选择持久化。如果exchange和queue都是持久化的,那么它们之间的binding也是持久化的。如果exchange和queue两者之间有一个持久化,一个非持久化,就不允许建立绑定。消息队列持久化包括3个部分:

(1)exchange持久化,在声明时指定durable => 1

(2)queue持久化,在声明时指定durable => 1

(3)消息持久化,在投递时指定delivery_mode=> 2(1是非持久化)

4.2交换机

声明交换机

AMQP_PUBLIC_FUNCTION amqp_exchange_declare_ok_t *AMQP_CALL amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel,amqp_bytes_t exchange, amqp_bytes_t type, amqp_boolean_t passive,amqp_boolean_t durable, amqp_boolean_t auto_delete, amqp_boolean_t internal,amqp_table_t arguments);

 

/**

 * amqp_exchange_declare

 *

 * @param [in] connect连接 amqp_new_connection获取

 * @param [in] channel the channel to do the RPC on,程序自己设置一个通道号,一个连接可以多个通道号。

 * @param [in] exchange 指定交换机名称 eg:amqp_cstring_bytes("exchange_cat")

 * @param [in] type 指定交换机类型,amqp_cstring_bytes("direct") 

 * "fanout" 广播的方式,发送到该exchange的所有队列上。

 * "direct" 通过路由键发送到指定的队列上。

 * "topic" 通过匹配路由键的方式获取,使用通配符*,#

 * @param [in] passive 检测exchange是否存在,设为true,若exchange存在则命令成功返回(调用其他参数不会影响exchange属性),若不存在不会创建exchange,返回错误。设为false,如果exchange不存在则创建exchange,调用成功返回。如果exchange已经存在,并且匹配现在exchange的话则成功返回,如果不匹配则exchange声明失败。

 * @param [in] durable 队列是否持久化

 * @param [in] auto_delete 连接断开的时候,exchange是否自动删除

 * @param [in] internal internal

 * @param [in] arguments arguments

 * @returns amqp_exchange_declare_ok_t

 */

 

Demo示例:


#include <amqp.h>
#include <amqp_tcp_socket.h>
void die_on_amqp_error2(amqp_rpc_reply_t x, char const *context) {
	char sLog[1024] = {0};
	switch (x.reply_type) {
	case AMQP_RESPONSE_NORMAL:
		return;

	case AMQP_RESPONSE_NONE:
		printf(sLog, "%s: missing RPC reply type!\n", context);
		break;

	case AMQP_RESPONSE_LIBRARY_EXCEPTION:
		printf(sLog, "%s: %s\n", context, amqp_error_string2(x.library_error));
		break;

	case AMQP_RESPONSE_SERVER_EXCEPTION:
		switch (x.reply.id) {
		case AMQP_CONNECTION_CLOSE_METHOD: {
			amqp_connection_close_t *m =
				(amqp_connection_close_t *)x.reply.decoded;
			printf(sLog, "%s: server connection error %uh, message: %.*s\n",
				context, m->reply_code, (int)m->reply_text.len,
				(char *)m->reply_text.bytes);
			break;
										   }
		case AMQP_CHANNEL_CLOSE_METHOD: {
			amqp_channel_close_t *m = (amqp_channel_close_t *)x.reply.decoded;
			printf(sLog, "%s: server channel error %uh, message: %.*s\n",
				context, m->reply_code, (int)m->reply_text.len,
				(char *)m->reply_text.bytes);
			break;
										}
		default:
			printf(sLog, "%s: unknown server error, method id 0x%08X\n",
				context, x.reply.id);
			break;
		}
		break;
	}

	AfxMessageBox(sLog);
}


void die_on_error2(int x, char const *context) {
	if (x < 0) {
		char sLog[1024] = {0};
		printf(sLog, "%s: %s\n", context, amqp_error_string2(x));
		AfxMessageBox(sLog);
	}
}

void Crabbitmq_demoDlg::OnBnClickedButton1()
{
	char const *hostname;
	int port, status;
	char const *exchange;
	char const *exchangetype;
	amqp_socket_t *socket = NULL;
	amqp_connection_state_t conn;

	hostname ="localhost";
	port = 5672;
	exchange = "test.fanout";
	exchangetype = "fanout"; //fanout/direct/topic

	conn = amqp_new_connection();

	socket = amqp_tcp_socket_new(conn);
	if (!socket) {
		AfxMessageBox("creating TCP socket");
	}

	status = amqp_socket_open(socket, hostname, port);
	if (status) {
		AfxMessageBox("opening TCP socket");
	}

	die_on_amqp_error2(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
		"guest", "guest"),
		"Logging in");
	amqp_channel_open(conn, 1);
	die_on_amqp_error2(amqp_get_rpc_reply(conn), "Opening channel");

	amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange),
		amqp_cstring_bytes(exchangetype), 0, 0, 0, 0,
		amqp_empty_table);
	die_on_amqp_error2(amqp_get_rpc_reply(conn), "Declaring exchange");

	die_on_amqp_error2(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS),
		"Closing channel");
	die_on_amqp_error2(amqp_connection_close(conn, AMQP_REPLY_SUCCESS),
		"Closing connection");
	die_on_error2(amqp_destroy_connection(conn), "Ending connection");
	int end = 0;
}

 

 

删除交换机

/**

&n

RabbitMQ C API 实现 RPC 通信实例 本文介绍了如何使用RabbitMQ的C API实现RPC(远程过程调用)功能。RPC允许程序调用远程服务,如同调用本地函数一样简单,具有异步通信、解耦合、负载均衡等优势。文章详细说明了环境搭建步骤,包括启动RabbitMQ服务和安装rabbitmq-c库。核心部分展示了服务端代码实现,通过监听请求队列、处理请求并返回响应来完成RPC调用。服务端代码涵盖了连接建立、队列声明、消息消费和响应发送等关键流程,并加入了错误处理和信号机制确保可靠性。该实例为C语言开发者提供了RabbitMQ实现分布式通信的完整参考方 阅读详情

相关推荐

RabbitMQ-C移植指南及示例代码

RabbitMQ提供了多种客户端库,其中RabbitMQ-C是用于C语言的官方客户端库。以上示例代码分别展示了RabbitMQ-C的生产者和消费者的基本实现。首先,您需要获取RabbitMQ-C的源代码。您可以从RabbitMQ官方网站下载最新版本的源代码包,解压后即可得到RabbitMQ-C的源代码。希望本文能帮助您理解RabbitMQ-C的移植过程,并为您的消息通信应用程序提供指导和示例代码。完成编译后,您可以分别运行生产者和消费者程序,并观察它们在RabbitMQ服务器上的交互。

VksgShapes的博客 537

RabbitMQ c++

RabbitMQ -c

u010549750的专栏 2139

SOLIDWORKS转CAD字体终极选择:TrueType vs SHX,哪个才是你图纸协作的“安全牌”?

本文深入探讨SOLIDWORKS转CAD工程图中的字体选择问题,对比TrueType与SHX字体在DWG文件协作中的表现。通过真实案例揭示字体映射的兼容性陷阱,提供企业级字体管理方案,帮助工程师规避版本差异、系统依赖和法律风险,确保图纸协作的稳定性。

weixin_34233974的博客 264

TVS 和压敏电阻联合使用进行浪涌保护时,压敏电阻的压敏电压要低于TVS 的钳位电压 VC。

通过先让MOV接管,可以确保在大多数情况下,电压不会迅速上升到TVS二极管的钳位电压,从而保护TVS二极管免受持续高能量冲击的损害。总结来说,将MOV的压敏电压设置得低于TVS二极管的钳位电压,可以提供一种分级的保护机制,优化浪涌保护性能,同时保护敏感的TVS二极管不被过度的能量冲击损坏,并延长其使用寿命。MOV吸收的能量(Wmov):假设浪涌电流为10kA,MOV导通后将电压限制在300V,那么Wmov = Ipp * Vmov = 10kA * 300V = 3MW。例如,Vmov可以设定为275V。

weixin_66642980的博客 2244

ITK-snap医学图像标注方法(超级详细)——保姆级

医学3D图像标注方法,非常详细,保姆级

jialiyk的博客 3万+

美军利用MANET技术实现无人作战单元协同作战

本文首先介绍了移动自组织网络 (MANET)以及Wave Relay®波形中继技术,并探讨了波形中继MANET平台在美空军ABMS项目等军事方面的运用情况。

guanyifu9的博客 849

开源的预测气象大模型与数据获取/可视化

「开源气象大模型与数据获取指南」摘要: 当前主流AI气象模型(如ECMWF的AIFS、DeepMind的GraphCast、华为Pangu等)主要基于ERA5/HRES数据训练。开源资源可通过ECMWF OpenData、GitHub仓库及Google Cloud获取,其中AIFS数据采用CCBY-4.0许可可商用,其他模型多有限制性许可。典型应用流程包括:1)通过Python包获取实时预报数据;2)加载预训练权重进行推理;3)使用xarray/cartopy或Zarr进行可视化。训练数据可从CDS下载ER

专注AI大模型,软件混淆,授权 792

Ubuntu系统下MRIcroN、FSL6.0.5、Freesurfer7.1.1、ANTs、MRtrix3、AFNI的安装详解——核磁共振数据处理必备

Ubuntu系统下MRIcroN、FSL6.05、Freesurfer7.1.1、MRtrix3、AFNI、ANTs的安装详解一、安装MRIcroN二、 FSL6.0.5完整安装与FSLeyes等Not Found修复Anaconda与虚拟环境(所有操作均在root下)获取最新版Anaconda3安装Anaconda3配置所有用户可用去掉恼人的base创建虚拟环境FSL与FSLeyes安装(所有操作均在root下)下载FSL安装FSL添加环境变量到/etc/bash.bashrc末尾 (ubuntu)或者

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 6085

10种电阻综合对比——《器件手册--电阻》

可变电阻在电子设备中也有很多用途,如在收音机的音量调节电路中,通过旋转可变电阻的旋钮来改变电路中的电阻值,从而改变通过扬声器的电流,实现音量的调节。根据电阻定律,电阻R = ρ(L/S),其中ρ是导体材料的电阻率,L是导体的长度,S是导体的横截面积。比如,同样材料制成的两根电线,粗的电线电阻比细的电线电阻小,长的电线电阻比短的电线电阻大。电流采样电阻的工作原理基于欧姆定律,即电阻两端的电压与通过电阻的电流成正比,公式为 I = V/R,其中 I是电流,V是电阻两端的电压,R 是电阻值。

XU157303764的博客 3138

USB驱动(URB)

本文介绍了Linux内核中USB驱动开发的核心概念URB(USB Request Block)。URB是主机与USB设备间传输数据的抽象结构体,包含目标设备、端点信息、数据缓冲区等关键字段。文章详细解析了URB的生命周期(分配、填充、提交、回调、释放)、四种传输类型(控制、批量、中断、等时)及其应用场景,并提供了鼠标设备的中断传输示例代码。最后强调了URB使用注意事项,包括DMA缓冲区分配、错误处理和资源释放等。URB作为USB驱动与内核通信的桥梁,是构建稳定USB驱动程序的基础。

m0_49476241的博客 915

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: redis在Windows下以后台服务一键搭建哨兵(主从复制)模式(多机)
下一篇: mongodb-c-driver使用详解----windows环境
MingoJiang
博客等级 码龄14年 161粉丝 41原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MingoJiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值