CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(demo)
set(CMAKE_CXX_STANDARD 17)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread -ldl")
# 设置头文件地址
set(INC_DIR /usr/)
# 设置动态库地址
set(LINK_DIR /usr/)
include_directories(${INC_DIR})
link_directories(${LINK_DIR})
# 生产者
add_executable(messageProducer helloworld/MessageProducer.cpp)
add_executable(messageConsumer helloworld/MessageConsumer.cpp)
add_executable(workProducer workqueue/WorkProducer.cpp)
add_executable(worker1 workqueue/WorkComsumer.cpp)
add_executable(worker2 workqueue/WorkComsumer.cpp)
add_executable(MessageProducer publishandsubscribe/MessageProducer.cpp)
add_executable(MessageConsumer1 publishandsubscribe/MessageConsumer1.cpp)
add_executable(MessageConsumer2 publishandsubscribe/MessageConsumer2.cpp)
add_executable(RoutingProducer routing/MessageProducer.cpp)
add_executable(RoutingConsumer1 routing/MessageConsumer1.cpp)
add_executable(RoutingConsumer2 routing/MessageConsumer2.cpp)
add_executable(TopicProducer topic/MessageProducer.cpp)
add_executable(TopicConsumer1 topic/MessageConsumer1.cpp)
add_executable(TopicConsumer2 topic/MessageConsumer2.cpp)
add_executable(TopicConsumer3 topic/MessageConsumer3.cpp)
add_executable(RpcServer rpc/RpcServer.cpp)
add_executable(RpcClient rpc/RpcClient.cpp)
add_executable(DeadLetterConsumer deadletter/DeadLetterConsumer.cpp)
add_executable(Producer deadletter/MessageProducer.cpp)
add_executable(Consumer deadletter/MessageConsumer.cpp)
# 将库连接到项目中
target_link_libraries(messageProducer libamqpcpp.so libevent_core.so)
target_link_libraries(messageConsumer libamqpcpp.so libevent_core.so)
target_link_libraries(workProducer libamqpcpp.so libevent_core.so)
target_link_libraries(worker1 libamqpcpp.so libevent_core.so)
target_link_libraries(worker2 libamqpcpp.so libevent_core.so)
target_link_libraries(MessageProducer libamqpcpp.so libevent_core.so)
target_link_libraries(MessageConsumer1 libamqpcpp.so libevent_core.so)
target_link_libraries(MessageConsumer2 libamqpcpp.so libevent_core.so)
target_link_libraries(RoutingProducer libamqpcpp.so libevent_core.so)
target_link_libraries(RoutingConsumer1 libamqpcpp.so libevent_core.so)
target_link_libraries(RoutingConsumer2 libamqpcpp.so libevent_core.so)
target_link_libraries(TopicProducer libamqpcpp.so libevent_core.so)
target_link_libraries(TopicConsumer1 libamqpcpp.so libevent_core.so)
target_link_libraries(TopicConsumer2 libamqpcpp.so libevent_core.so)
target_link_libraries(TopicConsumer3 libamqpcpp.so libevent_core.so)
target_link_libraries(RpcServer libamqpcpp.so libevent_core.so)
target_link_libraries(RpcClient libamqpcpp.so libevent_core.so)
target_link_libraries(DeadLetterConsumer libamqpcpp.so libevent_core.so)
target_link_libraries(Producer libamqpcpp.so libevent_core.so)
target_link_libraries(Consumer libamqpcpp.so libevent_core.so)
conn_handler
#include <functional>
#include <unistd.h>
#include <event2/event.h>
#include <amqpcpp/libevent.h>
class LibEventHandlerMyError : public AMQP::LibEventHandler
{
public:
LibEventHandlerMyError(struct event_base *evbase)
: LibEventHandler(evbase), evbase_(evbase_) {}
void onError(AMQP::TcpConnection *connection, const char *msg) override
{
std::cout << "Error: " << msg << std::endl;
event_base_loopbreak(evbase_);
}
private:
struct event_base *evbase_ = nullptr;
};
class ConnHandler
{
public:
using EventBasePtrT = std::unique_ptr<struct event_base, std::function<void(struct event_base *)>>;
using EventPtrT = std::unique_ptr<struct event, std::function<void(struct event *)>>;
ConnHandler()
: evbase_(event_base_new(), event_base_free),
// event_base_new是libevent库中的一个函数,用于创建一个新的事件基础(event base)对象。
// event_base_free是libevent库中的一个函数,用于释放之前通过event_base_new创建的事件基础对象所占用的内存。
stdin_event_(event_new(evbase_.get(), STDIN_FILENO, EV_READ, stop, evbase_.get()), event_free),
// event_new是libevent库中的一个函数,用于创建一个新的事件对象。
// event_free是libevent库中的一个函数,用于释放之前通过event_new创建的事件对象所占用的内存。
evhandler_(evbase_.get())
{
event_add(stdin_event_.get(), nullptr);
}
void Start()
{
std::cout << "Waiting for message. Press enter to exit." << std::endl;
event_base_dispatch(evbase_.get());
// event_base_dispatch是libevent库中的一个关键函数,主要用于启动和运行事件循环。
}
void Stop()
{
event_base_loopbreak(evbase_.get());
// event_base_loopbreak是libevent库中的一个函数,用于终止当前运行的事件循环。
}
operator AMQP::TcpHandler *()
{
return &evhandler_;
}
private:
static void stop(evutil_socket_t fd, short what, void *evbase)
{
std::cout << "Safely breaking event loop." << std::endl;
event_base_loopbreak(reinterpret_cast<event_base *>(evbase));
// event_base_loopbreak是libevent库中的一个函数,用于终止当前运行的事件循环。
}
EventBasePtrT evbase_;
EventPtrT stdin_event_;
LibEventHandlerMyError evhandler_;
};
简单模式
一个生产者,一个消费者,一个队列,采用默认交换机。可以理解为生产者P发送消息到队列Q,一个消费者C接收。
MessageProducer
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
auto evbase = event_base_new();
LibEventHandlerMyError handl(evbase);
// 建立连接
// TCP连接,是客户端与消息中间件建立通信的重要部分
AMQP::TcpConnection conn(&handl, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 服务地址格式为 amqp://username:password@host:port/vhost
// 建立通道
// 代表了在客户端与消息中间件之间建立的一条TCP连接上的一个信道
AMQP::TcpChannel channel(&conn);
channel.onError([&evbase](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
event_base_loopbreak(evbase);
});
// 声明消息队列
channel.declareQueue("hello_queue", AMQP::passive).onSuccess([](const std::string &name,
uint32_t messagecount,
uint32_t consumercount) {
std::cout << "Queue: " << name << std::endl;
}).onFinalize([&conn]() {
std::cout << "Finalize." << std::endl;
conn.close();
});
// 发送消息到消息队列
channel.publish("", "hello_queue", "Hello, World!");
event_base_dispatch(evbase);
event_base_free(evbase);
return 0;
}
MessageConsumer
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
ConnHandler handler;
AMQP::TcpConnection conn(handler, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
AMQP::TcpChannel channel(&conn);
channel.onError([&handler](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
handler.Stop();
});
channel.setQos(1);
// 设定最小交付信息次数为最少一次
channel.declareQueue("hello_queue", AMQP::durable);
channel.consume("hello_queue").onReceived([&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered){
std::cout << "Received: " << msg.body() << std::endl;
channel.ack(tag);
});
handler.Start();
std::cout << "Closing connection." << std::endl;
connection.close();
return 0;
}
工作模式
一个生产者,多个消费者,一个队列,采用默认交换机。可以理解为生产者P发送消息到队列Q,可以由多个消费者C1、C2进行接收。
WorkProducer
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
auto evbase = event_base_new();
LibEventHandlerMyError handl(evbase);
// 创建连接
AMQP::TcpConnection conn(&handl, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&evbase](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
event_base_loopbreak(evbase);
});
// 声明消息队列
channel.declareQueue("task_queue", AMQP::passive).onSuccess([](const std::string &name, uint32_t messagecount, uint32_t consumercount){
std::cout << "Queue: " << name << std::endl;
}).onFinalize([&conn](){
std::cout << "Finalize." << std::endl;
conn.close();
});
// 发送消息到消息队列
for(int i = 0; i < 10; ++i) {
channel.publish("", "task_queue", "hello client this is a work message");
}
event_base_dispatch(evbase);
event_base_free(evbase);
return 0;
}
WorkComsumer
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
ConnHandler handler;
// 创建连接
AMQP::TcpConnection conn(handler, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&handler](const char *msg){
std::cout << "channel error: " << message << std::endl;
handler.Stop();
});
// 声明消息队列
channel.setQos(1);
channel.declareQueue("task_queue", AMQP::durable);
channel.consume("task_queue").onReceived([&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered){
// 处理消息
std::cout << "Worker1 Received: " << msg.body() << std::endl;
// 回复ack
channel.ack(tag);
// 消费失败可回复reject
});
handler.Start();
std::cout << "Closing connection. " << std::endl;
conn.close();
return 0;
}
发布/订阅模式(fanout)
一个生产者、一个 fanout 类型的交换机、多个队列、多个消费者。一个生产者发送的消息会被多个消费者获取。其中 fanout 类型就是发布订阅模式,只有订阅该生产者的消费者会收到消息。
MessageProducer
#include <iostream>
#include <thread>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
auto evbase = event_base_new();
LibEventHandlerMyError handl(evbase);
// 建立连接
AMQP::TcpConnection conn(&handl, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&evbase](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
event_base_loopbreak(evbase);
});
// 声明交换机
channel.declareExchange("ps_exchange", AMQP::ExchangeType::fanout);
// 发送消息到交换机
for(int i = 0; i < 10; ++i) {
channel.publish("ps_exchange", "", "Hello client this is a ps message");
}
event_base_dispatch(evbase);
event_base_free(evbase);
return 0;
}
MessageConsumer1
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
ConnHandler handler;
// 建立连接
AMQP::TcpConnection conn(handler, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&handler](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("ps_change", AMQP::ExchangeType::fanout);
// 声明消息队列
channel.declareQueue("ps_queue", AMQP::durable);
// 绑定消息队列到交换机
channel.bindQueue("ps_exchange", "ps_queue", "");
channel.setQos(1);
// 订阅消息
channel.consume("ps_queue").onReceived([&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered){
// 处理消息
std::cout << "Received: " << msg.body() << std::endl;
// 回复ack
channel.ack(tag);
});
handler.Start();
std::cout << "Closing connection." << std::endl;
conn.close();
return 0;
}
MessageConsumer2
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "../conn_handler.h"
int main()
{
ConnHandler handler;
// 建立连接
AMQP::TcpConnection conn(handler, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&handler](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("ps_change", AMQP::ExchangeType::fanout);
// 声明消息队列
channel.declareQueue("ps_queue1", AMQP::durable);
// 绑定消息队列到交换机
channel.bindQueue("ps_exchange", "ps_queue1", "");
channel.setQos(1);
// 订阅消息
channel.consume("ps_queue1").onReceived([&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered){
// 处理消息
std::cout << "Received: " << msg.body() << std::endl;
// 回复ack
channel.ack(tag);
});
handler.Start();
std::cout << "Closing connection." << std::endl;
conn.close();
return 0;
}
路由模式(direct)
一个生产者,一个 direct 类型的交换机,多个队列,交换机与队列之间通过 routing-key 进行关联绑定,多个消费者。生产者发送消息到交换机并且要指定routing-key,然后消息根据这交换机与队列之间的 routing-key 绑定规则进行路由被指定消费者消费。
MessageProducer
#include <iostream>
#include <thread>
#include <amqpcpp.h>
#include "conn_handler.h"
int main() {
auto evbase = event_base_new();
LibEventHandlerMyError hndl(evbase);
// 建立连接
AMQP::TcpConnection connection(&hndl, AMQP::Address(
"amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&evbase](const char *message) {
std::cout << "Channel error: " << message << std::endl;
event_base_loopbreak(evbase);
});
// 声明交换机
channel.declareExchange("direct_exchange", AMQP::ExchangeType::direct);
// 发送消息到交换机
channel.publish("direct_exchange", "error", "Hello client this is a error message");
channel.publish("direct_exchange", "info", "Hello client this is a info message");
channel.publish("direct_exchange", "waring", "Hello client this is a waring message");
event_base_dispatch(evbase);
event_base_free(evbase);
return 0;
}
MessageConsumer1
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
ConnHandler handler;
// 建立连接
AMQP::TcpConnection conn(handler, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&handler](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("ps_change", AMQP::ExchangeType::fanout);
// 声明消息队列
channel.declareQueue("ps_queue", AMQP::durable);
// 绑定消息队列到交换机
channel.bindQueue("ps_exchange", "ps_queue", "");
channel.setQos(1);
// 订阅消息
channel.consume("ps_queue").onReceived([&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered){
// 处理消息
std::cout << "Received: " << msg.body() << std::endl;
// 回复ack
channel.ack(tag);
});
handler.Start();
std::cout << "Closing connection." << std::endl;
conn.close();
return 0;
}
MessageConsumer2
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main()
{
ConnHandler handler;
// 建立连接
AMQP::TcpConnection conn(handler, AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&conn);
channel.onError([&handler](const char *msg){
std::cout << "Channel error: " << msg << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("ps_change", AMQP::ExchangeType::fanout);
// 声明消息队列
channel.declareQueue("ps_queue1", AMQP::durable);
// 绑定消息队列到交换机
channel.bindQueue("ps_exchange", "ps_queue1", "");
channel.setQos(1);
// 订阅消息
channel.consume("ps_queue1").onReceived([&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered){
// 处理消息
std::cout << "Received: " << msg.body() << std::endl;
// 回复ack
channel.ack(tag);
});
handler.Start();
std::cout << "Closing connection." << std::endl;
conn.close();
return 0;
}
主题模式(topic)
一个生产者,一个 topic 类型的交换机,多个队列,交换机与队列之间通过 routing-key 进行关联绑定,多个消费者。生产者发送消息到交换机并且要指定 routing-key,然后消息根据这交换机与队列之间的 routing-key 绑定规则进行路由被指定消费者消费。与路由模式不同是 routing-key 有指定的队则,可以更加的通用,满足更过的场景。routing-key 的规则如下:
#
:匹配一个或者多个词,例如lazy.#
可以匹配 lazy.xxx 或者 lazy.xxx.xxx*
:只能匹配一个词,例如lazy.*
只能匹配 lazy.xxx
MessageProducer
#include <iostream>
#include <thread>
#include <amqpcpp.h>
#include "../conn_handler.h"
int main() {
auto evbase = event_base_new();
LibEventHandlerMyError hndl(evbase);
// 建立连接
AMQP::TcpConnection connection(&hndl, AMQP::Address(
"amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&evbase](const char *message) {
std::cout << "Channel error: " << message << std::endl;
event_base_loopbreak(evbase);
});
// 声明交换机
channel.declareExchange("topic_exchange", AMQP::ExchangeType::topic);
// 发送消息到交换机
channel.publish("topic_exchange", "aaa.bbb.ccc", "Hello client this is a aaa.bbb.ccc message");
channel.publish("topic_exchange", "ccc.bbb.aaa", "Hello client this is a ccc.bbb.aaa message");
channel.publish("topic_exchange", "aaa.aaa.aaa", "Hello client this is a aaa.aaa.aaa message");
channel.publish("topic_exchange", "aaa.yyy.zzz", "Hello client this is a aaa.yyy.zzz message");
channel.publish("topic_exchange", "xxx.yyy.zzz", "Hello client this is a xxx.yyy.zzz message");
event_base_dispatch(evbase);
event_base_free(evbase);
return 0;
}
MessageConsumer1
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "../conn_handler.h"
int main() {
ConnHandler handler;
// 建立连接
AMQP::TcpConnection connection(handler,
AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&handler](const char *message) {
std::cout << "Channel error: " << message << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("topic_exchange", AMQP::ExchangeType::topic);
// 生命消息队列
channel.declareQueue("topic_queue", AMQP::durable);
// 绑定消息队列到交换机
channel.bindQueue("topic_exchange", "topic_queue", "*.bbb.*");
channel.bindQueue("topic_exchange", "topic_queue", "aaa.#");
channel.bindQueue("topic_exchange", "topic_queue", "*.*.aaa");
channel.setQos(1);
// 订阅消息
channel.consume("topic_queue")
.onReceived
(
[&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered) {
std::cout << "Received: " << msg.body() << std::endl;
channel.ack(tag);
}
);
handler.Start();
std::cout << "Closing connection." << std::endl;
connection.close();
return 0;
}
MessageConsumer2
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "../conn_handler.h"
int main() {
ConnHandler handler;
// 建立连接
AMQP::TcpConnection connection(handler,
AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&handler](const char *message) {
std::cout << "Channel error: " << message << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("topic_exchange", AMQP::ExchangeType::topic);
// 声明消息队列
channel.declareQueue("topic_queue1", AMQP::durable);
// 绑定消息队列到指定交换机
channel.bindQueue("topic_exchange", "topic_queue1", "*.*.aaa");
channel.setQos(1);
// 订阅消息
channel.consume("topic_queue1")
.onReceived
(
[&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered) {
std::cout << "Received: " << msg.body() << std::endl;
channel.ack(tag);
}
);
handler.Start();
std::cout << "Closing connection." << std::endl;
connection.close();
return 0;
}
MessageConsumer3
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "../conn_handler.h"
int main() {
ConnHandler handler;
// 建立连接
AMQP::TcpConnection connection(handler,
AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&handler](const char *message) {
std::cout << "Channel error: " << message << std::endl;
handler.Stop();
});
// 声明交换机
channel.declareExchange("topic_exchange", AMQP::ExchangeType::topic);
// 声明消息队列
channel.declareQueue("topic_queue2", AMQP::durable);
// 绑定消息队列到交换机
channel.bindQueue("topic_exchange", "topic_queue2", "*.*.zzz");
channel.setQos(1);
// 订阅消息
channel.consume("topic_queue2")
.onReceived
(
[&channel](const AMQP::Message &msg, uint64_t tag, bool redelivered) {
std::cout << "Received: " << msg.body() << std::endl;
channel.ack(tag);
}
);
handler.Start();
std::cout << "Closing connection." << std::endl;
connection.close();
return 0;
}
RPC模式
RpcServer
#include <iostream>
#include <thread>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
// 模拟rpc业务
int fib(int n) {
switch (n) {
case 0:
return 0;
case 1:
return 1;
default:
return fib(n - 1) + fib(n - 2);
}
}
int main() {
ConnHandler handler;
// 建立连接
AMQP::TcpConnection connection(handler,
AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&handler](const char *message) {
std::cout << "Channel error: " << message << std::endl;
handler.Stop();
});
channel.setQos(1);
// 声明消息队列
channel.declareQueue("rpc_queue");
// 消费消息
channel.consume("")
.onReceived
(
[&channel](const AMQP::Message &m, uint64_t tag, bool) {
std::cout << "fib(" << m.body() << ")" << std::endl;
// 处理业务
std::string body = std::to_string(fib(std::stoi(m.body())));
AMQP::Envelope envelope(body.data(), sizeof(body.data()));
envelope.setCorrelationID(m.correlationID());
// 回复rpc
channel.publish("", m.replyTo(), envelope);
channel.ack(tag);
}
);
handler.Start();
std::cout << "Closing connection." << std::endl;
connection.close();
return 0;
}
RpcClient
#include <iostream>
#include <thread>
#include <sstream>
#include <chrono>
#include <amqpcpp.h>
#include "conn_handler.h"
int main() {
std::stringstream ss;
ss << std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()).count();
std::string correlation = ss.str();
ConnHandler handler;
// 创建连接
AMQP::TcpConnection connection(handler,
AMQP::Address("amqp://guanjiaa:Zjc20020221.@81.71.97.27:5672//"));
// 建立通道
AMQP::TcpChannel channel(&connection);
channel.onError([&handler](const char *message) {
std::cout << "Channel error: " << message << std::endl;
handler.Stop();
});
// 声明消息队列
channel.declareQueue(AMQP::exclusive)
.onSuccess
(
[&channel, correlation](const std::string &name, int, int) {
std::string body = "30";
AMQP::Envelope env(body.data(), sizeof(body.data()));
env.setCorrelationID(correlation);
env.setReplyTo(name);
channel.publish("", "rpc_queue", env);
std::cout << "Requesting fib(30)" << std::endl;
}
);
// 消费消息
channel.consume("", AMQP::noack)
.onReceived
(
[correlation, &handler](const AMQP::Message &m, uint64_t, bool) {
if (m.correlationID() != correlation)
return; // just skip it
std::cout << "Got " << m.body() << std::endl;
handler.Stop();
}
);
handler.Start();
std::cout << "Closing connection." << std::endl;
connection.close();
return 0;
}