first commit

This commit is contained in:
bing
2026-04-03 11:38:40 +08:00
commit b704b006c1
6 changed files with 336 additions and 0 deletions

64
CMakeLists.txt Normal file
View File

@@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.15)
project(xrabbitmqclient CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Boost REQUIRED)
find_package(simpleamqpclient CONFIG REQUIRED)
# 使用 generate_export_header(${PROJECT_NAME}) 时:
# - CMake 会自动生成一个头文件,其中包含导出宏
# - 宏名称是 项目名称的大写形式 + _EXPORT 后缀
include(GenerateExportHeader)
# ---------------------------------------------------------
# 2. 编译封装层为独立库
# ---------------------------------------------------------
add_library(${PROJECT_NAME}
include/RabbitMQClient.h
src/RabbitMQClient.cpp
)
generate_export_header(${PROJECT_NAME}
EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/include/XRabbitMQClient_export.h
)
# 🌟 新增修复:强制 MSVC 使用 UTF-8 编码编译,彻底消灭 C4819 和乱码导致的玄学报错
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /utf-8)
endif()
# 设置头文件搜索路径
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
)
# 🌟 修复项:隐藏底层依赖,使用 Conan 声明的准确目标名(小写)
target_link_libraries(${PROJECT_NAME} PRIVATE simpleamqpclient::simpleamqpclient boost::boost)
# 添加导出宏
target_compile_definitions(${PROJECT_NAME} PRIVATE XRABBITMQCLIENT_LIBRARY)
# ---------------------------------------------------------
# 3. 安装规则 (供 Conan 打包提取使用)
# ---------------------------------------------------------
include(GNUInstallDirs)
# 安装生成的库文件
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # Windows 下的 .dll
)
# 安装暴露给业务层的头文件 (注意:千万不要把 RabbitMQClient.cpp 安装出去)
install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/IMessageQueue.h
${CMAKE_CURRENT_SOURCE_DIR}/include/RabbitMQClient.h
${CMAKE_BINARY_DIR}/include/XRabbitMQClient_export.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

91
README_PACKAGE.md Normal file
View File

@@ -0,0 +1,91 @@
# XRabbitMQClient 独立包发布指南
## 1. 本地构建和测试包
### 在 XRabbitMQClient 目录下执行:
```bash
cd XRabbitMQClient
# 安装依赖
conan install . --build=missing -s build_type=Release -s compiler.cppstd=17
# 构建包
conan build .
# 创建本地包(会自动构建并打包)
conan create . -s build_type=Release -s compiler.cppstd=17
```
## 2. 发布到 Conan 远程仓库
### 2.1 配置远程仓库(如果还没有)
```bash
# 查看已配置的远程仓库
conan remote list
# 添加远程仓库(示例)
conan remote add my-conan-repo https://your-conan-server.com
```
### 2.2 上传包
```bash
# 上传到远程仓库
conan upload xrabbitmqclient/1.0.0 --remote=my-conan-repo --all
```
## 3. 在其他项目中使用 xrabbitmqclient
### 3.1 在你的项目 conanfile.py 中添加依赖:
```python
from conan import ConanFile
class MyProjectConan(ConanFile):
name = "myproject"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
def requirements(self):
self.requires("xrabbitmqclient/1.0.0")
```
### 3.2 在 CMakeLists.txt 中使用:
```cmake
find_package(xrabbitmqclient CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE xrabbitmqclient::xrabbitmqclient)
```
### 3.3 代码中使用:
```cpp
#include <RabbitMQClient.h>
int main() {
// 使用 XRabbitMQClient
auto client = std::make_unique<RabbitMQClient>();
// ...
return 0;
}
```
## 4. 项目结构说明
```
XRabbitMQClient/
├── conanfile.py # 独立包的 Conan 配置
├── CMakeLists.txt # CMake 构建配置
├── include/ # 公开头文件
│ ├── IMessageQueue.h
│ └── RabbitMQClient.h
└── src/ # 源代码
└── RabbitMQClient.cpp
```
## 5. 版本更新流程
1. 修改 `conanfile.py` 中的 `version` 字段
2. 提交代码变更
3. 运行 `conan create .` 创建新版本
4. 上传新版本到远程仓库

50
conanfile.py Normal file
View File

@@ -0,0 +1,50 @@
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
class XRabbitMQClientConan(ConanFile):
name = "xrabbitmqclient"
version = "1.0.0"
description = "A C++ wrapper for RabbitMQ based on Interface and Pimpl."
license = "MIT"
author = "XDL"
topics = ("rabbitmq", "amqp", "message-queue")
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}
exports_sources = "CMakeLists.txt", "src/*", "include/*"
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")
def layout(self):
cmake_layout(self)
def requirements(self):
self.requires("simpleamqpclient/2.5.1", transitive_headers=True, transitive_libs=True)
self.requires("boost/1.78.0")
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
deps = CMakeDeps(self)
deps.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.libs = ["xrabbitmqclient"]
self.cpp_info.requires = ["simpleamqpclient::simpleamqpclient", "boost::boost"]

19
include/IMessageQueue.h Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#include <string>
#include "XRabbitMQClient_export.h"
// 纯虚接口:隔离具体的消息队列实现
class XRABBITMQCLIENT_EXPORT IMessageQueue
{
public:
virtual ~IMessageQueue() = default;
// 连接到消息队列服务器
virtual bool Connect() = 0;
// 发送消息
virtual bool Publish(const std::string &routing_key, const std::string &message) = 0;
// 接收消息 (简单阻塞式示例)
virtual std::string Consume(const std::string &queue_name) = 0;
};

25
include/RabbitMQClient.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#include "IMessageQueue.h"
#include <memory>
#include <string>
class XRABBITMQCLIENT_EXPORT RabbitMQClient : public IMessageQueue
{
public:
// 传入必要的连接参数
RabbitMQClient(const std::string &host, int port, const std::string &username, const std::string &password);
// 注意:使用 unique_ptr 配合 Pimpl 时,析构函数必须在 .cpp 中实现
~RabbitMQClient() override;
// 实现接口方法
bool Connect() override;
bool Publish(const std::string &routing_key, const std::string &message) override;
std::string Consume(const std::string &queue_name) override;
private:
// Pimpl 核心:前向声明具体的实现类
struct Impl;
// 使用 unique_ptr 管理实现类的生命周期
std::unique_ptr<Impl> pimpl_;
};

87
src/RabbitMQClient.cpp Normal file
View File

@@ -0,0 +1,87 @@
#include "RabbitMQClient.h"
#include <iostream>
// 在这里引入第三方库的头文件!
// 这样使用该封装类的业务代码就不会被污染
#include <SimpleAmqpClient/SimpleAmqpClient.h>
// 定义内部实现结构体
struct RabbitMQClient::Impl
{
std::string host;
int port;
std::string username;
std::string password;
AmqpClient::Channel::ptr_t channel;
Impl(std::string h, int p, std::string u, std::string pwd)
: host(std::move(h)), port(p), username(std::move(u)), password(std::move(pwd)), channel(nullptr) {}
};
// 构造函数:初始化 pimpl_
RabbitMQClient::RabbitMQClient(const std::string &host, int port, const std::string &username, const std::string &password)
: pimpl_(std::make_unique<Impl>(host, port, username, password))
{
}
// 析构函数:必须在这里定义,此时 Impl 是完整类型unique_ptr 才能正确释放它
RabbitMQClient::~RabbitMQClient() = default;
bool RabbitMQClient::Connect()
{
try
{
// 创建连接
pimpl_->channel = AmqpClient::Channel::Create(
pimpl_->host, pimpl_->port, pimpl_->username, pimpl_->password);
return true;
}
catch (const std::exception &e)
{
std::cerr << "RabbitMQ Connection Failed: " << e.what() << std::endl;
return false;
}
}
bool RabbitMQClient::Publish(const std::string &routing_key, const std::string &message)
{
if (!pimpl_->channel)
return false;
try
{
// 确保队列存在 (实际项目中可能在初始化时统一声明)
pimpl_->channel->DeclareQueue(routing_key, false, true, false, false);
AmqpClient::BasicMessage::ptr_t msg = AmqpClient::BasicMessage::Create(message);
pimpl_->channel->BasicPublish("", routing_key, msg);
return true;
}
catch (const std::exception &e)
{
std::cerr << "Publish Failed: " << e.what() << std::endl;
return false;
}
}
std::string RabbitMQClient::Consume(const std::string &queue_name)
{
if (!pimpl_->channel)
return "";
try
{
pimpl_->channel->DeclareQueue(queue_name, false, true, false, false);
std::string consumer_tag = pimpl_->channel->BasicConsume(queue_name, "");
// 阻塞等待消息
AmqpClient::Envelope::ptr_t envelope = pimpl_->channel->BasicConsumeMessage(consumer_tag);
return envelope->Message()->Body();
}
catch (const std::exception &e)
{
std::cerr << "Consume Failed: " << e.what() << std::endl;
return "";
}
}