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 }