项目实现
在Linux机器上规划开发目录
-
MQClient:存放客户端模块的代码
-
MQCommon:存放通用代码,如上文提到的前置工具类、.proto文件
-
MQServer:用于存放服务端模块代码
-
MQTest:用于编写单元测试
-
TestCode:是我之前学习库函数时写的代码,可以忽略
-
ThirdLib:存放第三方库文件,如Protubuf库、Muduo库
在MQCommon中编写公共类
在MQCommon中编写message.proto文件
- 在开始正式项⽬功能模块代码编写之前,我们需要先提前做⼀件事情,就是将消息类型定义出来。⽽消息最终是需要进⾏持久化存储的,因此涉及到数据的序列化和反序列化,因此消息的类型定义我们使⽤protobuf来进⾏⽣成
// 协议版本声明
syntax = "proto3";
// 包命名空间(防止命名冲突)
package MQ;
/* ==================== 交换机类型枚举 ====================
* 定义消息队列中交换机的路由策略类型
*/
enum ExchangeType {
UNKNOWTYPE = 0; // 未知类型(默认值)
DIRECT = 1; // 直连交换机(精确匹配routing_key)
FANOUT = 2; // 扇出交换机(广播到所有绑定队列)
TOPIC = 3; // 主题交换机(支持通配符匹配)
};
/* ==================== 消息传递模式枚举 ====================
* 定义消息的持久化特性
*/
enum DeliveryMode {
UNKNOWMODE = 0; // 未知模式(默认值)
UNDURABLE = 1; // 非持久化(内存存储,重启丢失)
DURABLE = 2; // 持久化(磁盘存储,重启保留)
};
/* ==================== 消息基础属性 ====================
* 包含消息的元数据信息
*/
message BasicProperties{
string id = 1; // 消息唯一标识符(建议UUID格式)
DeliveryMode delivery_mode = 2; // 持久化模式(默认UNKNOWMODE)
string routing_key = 3; // 路由键(用于交换机消息分发)
};
/* ==================== 消息有效载荷 ====================
* 包含实际传输的数据内容
*/
message Payload {
BasicProperties properties = 1; // 消息属性(必填)
string body = 2; // 消息内容主体(业务数据)
string valid = 3; // 有效性标记(可扩展为校验码/签名)
};
/* ==================== 完整消息结构 ====================
* 包含载荷及存储位置信息
*/
message Message {
Payload payload = 1; // 消息载荷(必填)
uint32 offset = 2; // 消息在存储中的偏移量(字节单位)
uint32 length = 3; // 消息长度(字节单位)
};
-
编译得到message.pb.h 与message.pb.cc两个文件
protoc --cpp_out=./ ./message.proto
在MQCommon中编写request.proto文件
-
该文件负责自定义网络通信协议
-
实现的请求类型有:
-
创建channel
-
关闭 channel
-
创建 exchange
-
删除 exchange
-
创建 queue
-
删除 queue
-
创建 binding
-
删除 binding
-
发送 message
-
订阅 message
-
发送 ack
-
返回 message (服务器 -> 客⼾端)
-
syntax = "proto3";
package MQ;
import "message.proto";
//信道的打开与关闭
message openChannelRequest{
string rid = 1;
string cid = 2;
};
message closeChannelRequest{
string rid = 1;
string cid = 2;
};
//交换机的声明与删除
message declareExchangeRequest{
string rid = 1;
string cid = 2;
string exchange_name = 3;
ExchangeType exchange_type = 4;
bool durable = 5;
bool auto_delete = 6;
map<string, string> args = 7;
};
message deleteExchangeRequest{
string rid = 1;
string cid = 2;
string exchange_name = 3;
};
//队列的声明与删除
message declareQueueRequest{
string rid = 1;
string cid = 2;
string queue_name = 3;
bool exclusive = 4;
bool durable = 5;
bool auto_delete = 6;
map<string, string> args = 7;
};
message deleteQueueRequest{
string rid = 1;
string cid = 2;
string queue_name = 3;
};
//队列的绑定与解除绑定
message queueBindRequest{
string rid = 1;
string cid = 2;
string exchange_name = 3;
string queue_name = 4;
string binding_key = 5;
};
message queueUnBindRequest{
string rid = 1;
string cid = 2;
string exchange_name = 3;
string queue_name = 4;
};
//消息的发布
message basicPublishRequest {
string rid = 1;
string cid = 2;
string exchange_name = 3;
string body = 4;
BasicProperties properties = 5;
};
//消息的确认
message basicAckRequest {
string rid = 1;
string cid = 2;
string queue_name = 3;
string message_id = 4;
};
//队列的订阅
message basicConsumeRequest {
string rid = 1;
string cid = 2;
string consumer_tag =3;
string queue_name = 4;
bool auto_ack = 5;
};
//订阅的取消
message basicCancelRequest {
string rid = 1;
string cid = 2;
string consumer_tag = 3;
string queue_name = 4;
};
//消息的推送
message basicConsumeResponse {
string cid = 1;
string consumer_tag = 2;
string body = 3;
BasicProperties properties = 4;
};
//通用响应
message basicCommonResponse {
string rid = 1;
string cid = 2;
bool ok = 3;
}
-
编译得到request.pb.h 与request.pb.cc两个文件
protoc --cpp_out=./ ./request.proto
在MQCommon中编写Helper.hpp文件
- 该文件包含的工具类(已在**“前置工具类的编写”**一节给出源码):
- UUID生成器类
- 字符串操作类
- SQLite操作类
- 文件基础操作类
在MQCommon中编写Logger.hpp文件
- 该文件里包含日志打印类,已在**“前置工具类的编写”**一节给出源码
在MQCommon中编写ThreadPool.hpp文件
- 该文件包含异步工作线程池类,已在**“前置工具类的编写”**一节给出源码