Cmake + VS2019 + boost 1.78.0 + rabbitmq-c编译SimpleAmqpClient
1.使用CMKAE + VS2019编译rabbitmq-c库
下载rabbitmq-c githup源码https://github.com/alanxz/rabbitmq-c
国内https://gitee.com/mirrors/rabbitmq-c
新建build 和 install 安装目录打开CMKAE工具配置
点击Configure
修改安装目录点击Generate 点击Open Project 或者去Bulid目录下打开生成的rabbitmq-c.sln 原理上一样
选择Release版本在编译rabbitmq 和rabbitmq_static
在build 目录下打开打开选择Release 在生成
install 目录下生成头文件 静态库 和 动态库
2使用CMake + VS2019 编译SimpleAmqpClient-master库
同样新建build 和install目录使用CMake 工具配置
出现如下错误,boost版本是1.47.0 我用的是1.78.0修改CMakelists.txt文件
再次点击Configure 出现如下错误
引入boost库
引入rabbitmq_c库
打开工程最终输出
3发布订阅模式
#include <SimpleAmqpClient/SimpleAmqpClient.h>
#include <iostream>
#include <string>
#include <thread>
using namespace std;
void test4()
{
std::thread project([](){
std::string exchange_name = "ex1";
std::string queue_name1 = "queue1";
std::string queue_name2 = "queue2";
// 1 连接MQ 服务器并创建channel
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
// 2 建立交换机
//参数1:交换机名字
//参数2:交换机类型
//参数3:passive: 这个参数指示了当交换机不存在时,代理(broker)应该如何反应。如果 passive 设置为 true,并且交换机不存在,代理将会返回一个错误而不创建交换机;否则,会创建交换机。默认情况下,passive 是 false,如果需要的话会创建交换机。
//参数4:这个参数指示了交换机是否是持久的,即它是否能够在代理重新启动后继续存在。如果设置为 true,交换机将会被持久化,否则不会。持久的交换机会将其定义保存到磁盘上,以便在代理重新启动后重新加载。
//参数5:这个参数指示了当没有队列绑定到交换机时,交换机是否会自动删除。如果设置为 true,当没有队列绑定到交换机时,交换机会自动被删除;否则,交换机不会自动删除。这在一些临时交换机的场景下很有用,例如用于临时数据传输的交换机。
channel->DeclareExchange(exchange_name, "fanout");
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name1 = channel->DeclareQueue(queue_name1, false, false, false, false, AmqpClient::Table());
queue_name2 = channel->DeclareQueue(queue_name2, false, false, false, false, AmqpClient::Table());
//4.绑定交换机和队列
channel->BindQueue(queue_name1, exchange_name);
channel->BindQueue(queue_name2, exchange_name);
while (true)
{
std::string sendMsg = "hello world";
//exchange_name: 要发布消息的交换机的名称
//exchange_name: 要发布消息的交换机的名称
//exchange_name: 要发布消息的交换机的名称
//mandatory: 设置为 true 时,要求消息必须被投递到队列。如果消息无法路由到队列,则会抛出 MessageReturnedException 异常。
//immediate: 设置为 true 时,要求消息必须被路由到队列,并立即传递给消费者。如果消息无法被路由,或者消费者无法立即接收消息,则会抛出 MessageReturnedException 异常。
//在使用 RabbitMQ v3.0 及更新版本时,此参数不起作用
channel->BasicPublish(exchange_name, "", AmqpClient::BasicMessage::Create(sendMsg));
std::this_thread::sleep_for(std::chrono::microseconds(10));
}
});
std::thread conumer1([](){
std::string exchange_name = "ex1";
std::string queue_name1 = "queue1";
// 打开 AMQP 通道
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name1 = channel->DeclareQueue(queue_name1, false, false, false, false, AmqpClient::Table());
std::string consumer_tag1 = "queue1";
consumer_tag1 = channel->BasicConsume(queue_name1, consumer_tag1);
while (true)
{
// 接收消息
AmqpClient::Envelope::ptr_t envelope;
bool success = channel->BasicConsumeMessage(consumer_tag1, envelope);
if (success)
{
// 处理消息
std::string received_message_body = envelope->Message()->Body();
std::cout << "Received message: " << std::this_thread::get_id() << ":" << received_message_body << std::endl;
}
}
});
std::thread conumer2([&]() {
std::string exchange_name = "ex1";
std::string queue_name2 = "queue2";
// 打开 AMQP 通道
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name2 = channel->DeclareQueue(queue_name2, false, false, false, false, AmqpClient::Table());
std::string consumer_tag2 = "queue1";
consumer_tag2 = channel->BasicConsume(queue_name2, consumer_tag2);
while (true)
{
// 接收消息
AmqpClient::Envelope::ptr_t envelope;
bool success = channel->BasicConsumeMessage(consumer_tag2, envelope);
if (success)
{
// 处理消息
std::string received_message_body = envelope->Message()->Body();
std::cout << "Received message: " <<std::this_thread::get_id()<< ":" << received_message_body << std::endl;
}
}
});
project.join();
conumer1.join();
conumer1.join();
}
int main()
{
test4();
}
4路由模式
void test5()
{
std::thread project([]() {
std::string exchange_name = "ex2";
std::string queue_name1 = "queue3";
std::string queue_name2 = "queue4";
// 1 连接MQ 服务器并创建channel
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
// 2 建立交换机
//参数1:交换机名字
//参数2:交换机类型
//参数3:passive: 这个参数指示了当交换机不存在时,代理(broker)应该如何反应。如果 passive 设置为 true,并且交换机不存在,代理将会返回一个错误而不创建交换机;否则,会创建交换机。默认情况下,passive 是 false,如果需要的话会创建交换机。
//参数4:这个参数指示了交换机是否是持久的,即它是否能够在代理重新启动后继续存在。如果设置为 true,交换机将会被持久化,否则不会。持久的交换机会将其定义保存到磁盘上,以便在代理重新启动后重新加载。
//参数5:这个参数指示了当没有队列绑定到交换机时,交换机是否会自动删除。如果设置为 true,当没有队列绑定到交换机时,交换机会自动被删除;否则,交换机不会自动删除。这在一些临时交换机的场景下很有用,例如用于临时数据传输的交换机。
channel->DeclareExchange(exchange_name, "direct");
channel->DeleteQueue(queue_name1);
channel->DeleteQueue(queue_name2);
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name1 = channel->DeclareQueue(queue_name1, false, false, false, false, AmqpClient::Table());
queue_name2 = channel->DeclareQueue(queue_name2, false, false, false, false, AmqpClient::Table());
//4.绑定交换机和队列
channel->BindQueue(queue_name1, exchange_name,"error");
channel->BindQueue(queue_name2, exchange_name,"error");
channel->BindQueue(queue_name2, exchange_name, "info");
channel->BindQueue(queue_name2, exchange_name, "waining");
channel->BindQueue(queue_name2, exchange_name, "debug");
while (true)
{
std::string sendMsg = "hello world";
//exchange_name: 要发布消息的交换机的名称
//exchange_name: 要发布消息的交换机的名称
//exchange_name: 要发布消息的交换机的名称
//mandatory: 设置为 true 时,要求消息必须被投递到队列。如果消息无法路由到队列,则会抛出 MessageReturnedException 异常。
//immediate: 设置为 true 时,要求消息必须被路由到队列,并立即传递给消费者。如果消息无法被路由,或者消费者无法立即接收消息,则会抛出 MessageReturnedException 异常。
//在使用 RabbitMQ v3.0 及更新版本时,此参数不起作用
channel->BasicPublish(exchange_name, "waining", AmqpClient::BasicMessage::Create(sendMsg));
std::this_thread::sleep_for(std::chrono::microseconds(10));
}
});
std::thread conumer1([]() {
std::string queue_name1 = "queue3";
// 打开 AMQP 通道
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name1 = channel->DeclareQueue(queue_name1, false, false, false, false, AmqpClient::Table());
std::string consumer_tag1 = "queue3";
consumer_tag1 = channel->BasicConsume(queue_name1, consumer_tag1);
while (true)
{
// 接收消息
AmqpClient::Envelope::ptr_t envelope;
bool success = channel->BasicConsumeMessage(consumer_tag1, envelope);
if (success)
{
// 处理消息
std::string received_message_body = envelope->Message()->Body();
std::cout << "Received message: " << std::this_thread::get_id() << ":" << received_message_body << std::endl;
}
}
});
std::thread conumer2([&]() {
std::string queue_name2 = "queue4";
// 打开 AMQP 通道
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name2 = channel->DeclareQueue(queue_name2, false, false, false, false, AmqpClient::Table());
std::string consumer_tag2 = "queue4";
consumer_tag2 = channel->BasicConsume(queue_name2, consumer_tag2);
while (true)
{
// 接收消息
AmqpClient::Envelope::ptr_t envelope;
bool success = channel->BasicConsumeMessage(consumer_tag2, envelope);
if (success)
{
// 处理消息
std::string received_message_body = envelope->Message()->Body();
std::cout << "Received message: " << std::this_thread::get_id() << ":" << received_message_body << std::endl;
}
}
});
project.join();
conumer1.join();
conumer2.join();
}
int main()
{
test5();
}
5.Topic模式
void test6()
{
std::thread project([]() {
std::string exchange_name = "ex3";
std::string queue_name1 = "queue5";
std::string queue_name2 = "queue6";
// 1 连接MQ 服务器并创建channel
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
// 2 建立交换机
//参数1:交换机名字
//参数2:交换机类型
//参数3:passive: 这个参数指示了当交换机不存在时,代理(broker)应该如何反应。如果 passive 设置为 true,并且交换机不存在,代理将会返回一个错误而不创建交换机;否则,会创建交换机。默认情况下,passive 是 false,如果需要的话会创建交换机。
//参数4:这个参数指示了交换机是否是持久的,即它是否能够在代理重新启动后继续存在。如果设置为 true,交换机将会被持久化,否则不会。持久的交换机会将其定义保存到磁盘上,以便在代理重新启动后重新加载。
//参数5:这个参数指示了当没有队列绑定到交换机时,交换机是否会自动删除。如果设置为 true,当没有队列绑定到交换机时,交换机会自动被删除;否则,交换机不会自动删除。这在一些临时交换机的场景下很有用,例如用于临时数据传输的交换机。
channel->DeclareExchange(exchange_name, "topic");
//channel->DeleteQueue(queue_name1);
//channel->DeleteQueue(queue_name2);
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name1 = channel->DeclareQueue(queue_name1, false, false, false, false, AmqpClient::Table());
queue_name2 = channel->DeclareQueue(queue_name2, false, false, false, false, AmqpClient::Table());
//4.绑定交换机和队列
channel->BindQueue(queue_name1, exchange_name, "error.*");
channel->BindQueue(queue_name2, exchange_name, "info.*");
while (true)
{
std::string sendMsg = "hello world";
//exchange_name: 要发布消息的交换机的名称
//exchange_name: 要发布消息的交换机的名称
//exchange_name: 要发布消息的交换机的名称
//mandatory: 设置为 true 时,要求消息必须被投递到队列。如果消息无法路由到队列,则会抛出 MessageReturnedException 异常。
//immediate: 设置为 true 时,要求消息必须被路由到队列,并立即传递给消费者。如果消息无法被路由,或者消费者无法立即接收消息,则会抛出 MessageReturnedException 异常。
//在使用 RabbitMQ v3.0 及更新版本时,此参数不起作用
channel->BasicPublish(exchange_name, "error.12312", AmqpClient::BasicMessage::Create(sendMsg));
std::this_thread::sleep_for(std::chrono::microseconds(10));
}
});
std::thread conumer1([]() {
std::string queue_name1 = "queue5";
// 打开 AMQP 通道
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name1 = channel->DeclareQueue(queue_name1, false, false, false, false, AmqpClient::Table());
std::string consumer_tag1 = "queue5";
consumer_tag1 = channel->BasicConsume(queue_name1, consumer_tag1);
while (true)
{
// 接收消息
AmqpClient::Envelope::ptr_t envelope;
bool success = channel->BasicConsumeMessage(consumer_tag1, envelope);
if (success)
{
// 处理消息
std::string received_message_body = envelope->Message()->Body();
std::cout << "Received message: " << std::this_thread::get_id() << ":" << received_message_body << std::endl;
}
}
});
std::thread conumer2([&]() {
std::string queue_name2 = "queue6";
// 打开 AMQP 通道
AmqpClient::Channel::ptr_t channel = AmqpClient::Channel::Create();
//3.建立队列
//参数1:queue_name: 指定队列的名称。如果这是一个空字符串,代理将生成一个队列名称,并且此方法将返回该名称。
//参数2:passive : 指示代理在队列不存在时如何响应。如果 passive 设置为 true,并且队列不存在,代理将会引发一个错误;如果 passive 设置为 false(默认值),则会自动创建队列。
//参数3:durable : 指示队列是否是持久的,即它是否能够在代理重新启动后继续存在。
//参数4:exclusive : 指示队列是否是排他的,即是否只能由客户端使用。默认情况下为 true。排他队列在连接关闭时会被自动删除。
//参数5:auto_delete : 指示当至少有一个交换机绑定到队列后,队列是否会自动删除。
//参数6:arguments : 附加参数的表格。
queue_name2 = channel->DeclareQueue(queue_name2, false, false, false, false, AmqpClient::Table());
std::string consumer_tag2 = "queue6";
consumer_tag2 = channel->BasicConsume(queue_name2, consumer_tag2);
while (true)
{
// 接收消息
AmqpClient::Envelope::ptr_t envelope;
bool success = channel->BasicConsumeMessage(consumer_tag2, envelope);
if (success)
{
// 处理消息
std::string received_message_body = envelope->Message()->Body();
std::cout << "Received message: " << std::this_thread::get_id() << ":" << received_message_body << std::endl;
}
}
});
project.join();
conumer1.join();
conumer2.join();
}
int main()
{
test6();
}