1 // 以DIRECT 交换机和ROUTING_KEY的方式进行消息的发布与订阅
2 // send
3 // strUri = "amqp://guest:guest@192.168.30.11:8820/test"
4 // strUri = "amqp://[帐户名]:[密码]@[服务主机以及端口]/[虚拟机目录]
5 bool PublicshExchangeDirect(const std::string &strUri, const std::string &strDirectExchange)
6 {
7 // 连接到rabbitMQ 服务器
8 AmqpClient::Channel::ptr_t channel =
9 AmqpClient::Channel::CreateFromUri(strUri);
10 if (channel == nullptr)
11 {
12 std::cout << "channel is nullptr" << std::endl;
13 return false;
14 }
15
16 // 创建指定类型的交换 机
17 channel->DeclareExchange(strDirectExchange, AmqpClient::Channel::EXCHANGE_TYPE_DIRECT);
18
19 while (true)
20 {
21 // 发送消息,例 :
22 // > info info infomation
23 // > trace trace infomation
24 // > debug debug infomation
25 // > error error infomation
26 std::string strSeverity;
27 std::string strBody;
28 std::cout << "Enter [severity info]: ";
29 std::cin >> strSeverity;
30 std::getline(std::cin, strBody);
31 if (strBody == "quit")
32 break;
33 if (strBody.empty())
34 continue;
35
36 std::cout << "strSeverity: " << strSeverity << "." << std::endl;
37 std::cout << "strBody: " << strBody << "." << std::endl;
38
39 // 发布消息到rabbitMQ
40 // strSeverity 指定该消息的routing_key, 在接收端 只有绑定了该routing_key 的队列 才会接收到该消息。
41 channel->BasicPublish(strDirectExchange, strSeverity,
42 AmqpClient::basicMessage::Create(strBody));
43
44 std::cout << "publicsh: " << strBody << std::endl;
45 }
46
47 return true;
48 }
49
50 // receive
51 void ReceiveDirectExchange(const std::string &strUri, const std::string &strDirectExchange)
52 {
53 AmqpClient::Channel::ptr_t channel =
54 AmqpClient::Channel::CreateFromUri(strUri);
55 if (channel == nullptr)
56 {
57 std::cout << "failed" << std::endl;
58 return;
59 }
60
61 // 创建指定类型的交换机,我们将从该交换 机中读取消息
62 channel->DeclareExchange(strDirectExchange, AmqpClient::Channel::EXCHANGE_TYPE_DIRECT);
63
64 std::string strQName = "queue_direct";
65 // 第一个参数为空,则系统默认生成随机名称
66 // 第三个参数(durable)表明队列 是否持久化
67 // durable:true、false。 true:服务器重启会保留下来Exchange。
68 // 警告:仅设置此选项,不代表消息持久化。即不保证重启后消息还在。
69 channel->DeclareQueue(strQName, false, true, false, false);
70
71 // 队列绑定我们感 兴趣的routing_key, 表示 我们只接收这些routing_key 相关的消息。
72 channel->BindQueue(strQName, strDirectExchange, "info");
73 channel->BindQueue(strQName, strDirectExchange, "trace");
74 channel->BindQueue(strQName, strDirectExchange, "error");
75
76 // 得到消费者的相关标记,用于订阅rabbitMQ 上的指定消息。
77 // 将第4个参数改为false,开启消息确认。
78 // 需要调用channel->BasicAck(xxx);
79 // 服务器上面的消息才会被清除,否则将一直保留在rabbitMQ 服务端 。
80 // 将第5个参数改为false,取消独占队列。
81 std::string strConsumer = channel->BasicConsume(strQName, "", true, false, false, 1);
82
83 while (true)
84 {
85 std::cout << "[RECIVE]: ";
86 AmqpClient::Envelope::ptr_t envelope =
87 channel->BasicConsumeMessage(strConsumer);
88
89 std::cout << envelope->Message()->Body() << std::endl;
90 // 下面两个接口是一样的
91 channel->BasicAck(envelope);
92 // channel->BasicAck(envelope->GetDeliveryInfo());
93 }
94
95 channel->BasicCancel(consumer_tag);
96 }