再写一个版本,要求使用类进行封装,提供完善的接口,并对函数进行完善注释
作者:linux大本营
- 2023-04-24 湖南
本文字数:2447 字
阅读完需:约 8 分钟
以下是一个使用 C++和 AMQP-CPP 库封装 RabbitMQ 的示例代码,提供了更完善的接口,并且对代码进行了注释:
#include <string>
#include <iostream>
#include <amqpcpp.h>
#include <amqpcpp/libboostasio.h>
/**
* 用于AMQP连接和通道的RAII类
*/
class AmqpConnection {
public:
/**
* @brief 构造函数,创建一个新的AMQP连接和通道
* @param connectionString RabbitMQ服务器的连接字符串
*/
AmqpConnection(const std::string& connectionString) :
mConnectionString(connectionString),
mIoService(),
mConnection(&mIoService, AMQP::Address(connectionString)),
mChannel(&mConnection)
{}
/**
* @brief 发布一条消息到指定的交换机
* @param exchangeName 交换机名
* @param routingKey 路由键(可选)
* @param message 消息内容
*/
void publishMessage(const std::string& exchangeName, const std::string& routingKey, const std::string& message) {
// 设置消息
AMQP::Envelope envelope(message.c_str(), message.length());
envelope.setRoutingKey(routingKey);
// 发布消息
mChannel.publish(exchangeName, "", envelope);
}
/**
* @brief 启动事件循环,接收和处理传入的数据
*/
void run() {
mIoService.run();
}
private:
const std::string mConnectionString;
boost::asio::io_service mIoService;
AMQP::TcpConnection mConnection;
AMQP::TcpChannel mChannel;
};
/**
* 用于AMQP连接处理的RAII类
*/
class AmqpConnectionHandler : public AMQP::ConnectionHandler {
public:
AmqpConnectionHandler(AmqpConnection& connection) : mConnection(connection) {}
/**
* @brief 重写AMQP::ConnectionHandler的onData函数,用于处理传入的消息
*/
virtual void onData(AMQP::Connection *connection, const char *data, size_t size) {
// 解析收到的消息
AMQP::Envelope envelope;
if (envelope.decode(data, size)) {
// 从解析的消息中获取信息
std::string exchangeName = envelope.exchange();
std::string routingKey = envelope.routingkey();
std::string message = envelope.message();
// 调用已注册的回调函数处理消息
auto callback = mMessageCallbacks.find(exchangeName);
if (callback != mMessageCallbacks.end()) {
callback->second(routingKey, message);
}
}
}
/**
* @brief 注册一个回调函数,用于处理收到的消息
* @param exchangeName 交换机名
* @param callback 回调函数
*/
void registerMessageCallback(const std::string& exchangeName, const std::function<void(const std::string&, const std::string&)>& callback) {
mMessageCallbacks[exchangeName] = callback;
}
private:
std::map<std::string, std::function<void(const std::string&, const std::string&)>> mMessageCallbacks;
AmqpConnection& mConnection;
};
/**
* 用于发送和接收AMQP消息的类
*/
class AmqpMessageQueue {
public:
/**
* @brief 构造函数,创建一个新的AMQP连接和通道
* @param connectionString RabbitMQ服务器的连接字符串
*/
AmqpMessageQueue(const std::string& connectionString) :
mConnection(connectionString),
mHandler(mConnection),
mStopped(false)
{
mHandler.setConnectionHandler(&mHandler);
}
/**
* @brief 注册一个回调函数,用于处理收到的消息
* @param exchangeName 交换机名
* @param callback 回调函数
*/
void registerMessageCallback(const std::string& exchangeName, const std::function<void(const std::string&, const std::string&)>& callback) {
mHandler.registerMessageCallback(exchangeName, callback);
}
/**
* @brief 发布一条消息到指定的交换机
* @param exchangeName 交换机名
* @param routingKey 路由键(可选)
* @param message 消息内容
*/
void publishMessage(const std::string& exchangeName, const std::string& routingKey, const std::string& message) {
mConnection.publishMessage(exchangeName, routingKey, message);
}
/**
* @brief 启动事件循环,接收和处理传入的数据
*/
void run() {
mStopped = false;
while (!mStopped) {
mConnection.run();
}
}
/**
* @brief 停止事件循环
*/
void stop() {
mStopped = true;
}
private:
AmqpConnection mConnection;
AmqpConnectionHandler mHandler;
bool mStopped;
};
int main() {
// 创建一个AMQP消息队列
AmqpMessageQueue messageQueue("amqp://username:password@host:port/vhost");
// 注册一个回调函数处理消息
messageQueue.registerMessageCallback("my_exchange", [](const std::string& routingKey, const std::string& message) {
std::cout << "Received message with routing key '" << routingKey << "' on 'my_exchange': " << message << std::endl;
});
// 启动事件循环,开始接收和处理消息
messageQueue.run();
return 0;
}
复制代码
在更高级别上使用 RAII 方法,我们利用封装来避免使用细致而冗长的代码。由于引用使用 RAII 提供了对连接、通道和连接处理对象实例的所有权管理,所以我们可以在对象脱离范围时隐式断开连接和释放所有资源。
类 AmqpConnection 是一个特殊的构造类,可以被其他类继承,如 AmqpMessageQueue。这样也允许您编写新的类,将 AmqpConnection 作为成员变量,进一步封装不同的网络协议以进行更高级别的通信。
相关技术视频教程:c/c++ linux服务器开发/后台架构师免费学习地址
划线
评论
复制
发布于: 刚刚阅读数: 3
linux大本营
关注
还未添加个人签名 2020-11-26 加入
C/C++linux服务器开发群 812855908
评论