写点什么

再写一个版本,要求使用类进行封装,提供完善的接口,并对函数进行完善注释

作者: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服务器开发/后台架构师免费学习地址

用户头像

还未添加个人签名 2020-11-26 加入

C/C++linux服务器开发群 812855908

评论

发布
暂无评论
再写一个版本,要求使用类进行封装,提供完善的接口,并对函数进行完善注释_RabbitMQ_linux大本营_InfoQ写作社区