SimpleAmqpClient 编译使用

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();
}

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值