- 信道管理模块
- 连接管理模块
- 服务器模块
信道管理模块
一、模块概述
信道模块是自研消息队列的会话层核心组件,基于 Muduo 网络库与 Protobuf 协议实现,作为客户端与服务端交互的唯一桥梁。负责接收并处理客户端全部业务请求:交换机声明删除、队列声明删除、队列绑定解绑、消息发布、消息确认、消费者订阅与取消订阅。
采用 Channel + ChannelManager 双层架构:
- Channel:单客户端会话信道,封装连接、协议编解码、消费者、虚拟主机、线程池等上下文;
- ChannelManager:全局信道管理器,统一维护所有信道生命周期,保证并发线程安全。
模块依托路由匹配、消费者管理、虚拟主机、线程池等底层模块,实现协议解析、路由转发、消息入队、异步推送、资源自动回收全链路能力,适配高并发多客户端接入场景。
二、核心架构与依赖
1. 架构分层
- Channel:业务逻辑载体,处理单条连接的所有 MQ 协议请求;
- ChannelManager:全局信道容器,线程安全管理信道创建、销毁、查找;
- 底层依赖:虚拟主机、消费者管理器、路由匹配模块、线程池、Protobuf 编解码器、Muduo TCP 连接。
2. 核心设计特性
- 统一协议响应封装,标准化客户端交互;
- 线程安全管控,细粒度互斥锁保障并发;
- 信道析构自动清理消费者,无订阅残留、无内存泄漏;
- 消息消费异步化,线程池解耦网络线程与业务消费;
- 智能指针全生命周期托管,资源自动释放。
三、完整源码实现
mq_channel.hpp
cpp
#ifndef __M_CHANNEL_H__
#define __M_CHANNEL_H__
#include "muduo/net/TcpConnection.h"
#include "muduo/proto/codec.h"
#include "muduo/proto/dispatcher.h"
#include "../mqcommon/mq_logger.hpp"
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_msg.pb.h"
#include "../mqcommon/mq_proto.pb.h"
#include "../mqcommon/mq_threadpool.hpp"
#include "mq_consumer.hpp"
#include "mq_host.hpp"
#include "mq_route.hpp"
namespace Fy_mq{
using ProtobufCodecPtr = std::shared_ptr<ProtobufCodec>;
using openChannelRequestPtr = std::shared_ptr<openChannelRequest>;
using closeChannelRequestPtr = std::shared_ptr<closeChannelRequest>;
using declareExchangeRequestPtr = std::shared_ptr<declareExchangeRequest>;
using deleteExchangeRequestPtr = std::shared_ptr<deleteExchangeRequest>;
using declareQueueRequestPtr = std::shared_ptr<declareQueueRequest>;
using deleteQueueRequestPtr = std::shared_ptr<deleteQueueRequest>;
using queueBindRequestPtr = std::shared_ptr<queueBindRequest>;
using queueUnBindRequestPtr = std::shared_ptr<queueUnBindRequest>;
using basicPublishRequestPtr = std::shared_ptr<basicPublishRequest>;
using basicAckRequestPtr = std::shared_ptr<basicAckRequest>;
using basicConsumeRequestPtr = std::shared_ptr<basicConsumeRequest>;
using basicCancelRequestPtr = std::shared_ptr<basicCancelRequest>;
using basicConsumeResponsePtr = std::shared_ptr<basicConsumeResponse>;
using basicCommonResponsePtr = std::shared_ptr<basicCommonResponse>;
class Channel{
public:
using ptr = std::shared_ptr<Channel>;
Channel(const std::string &id,
const VirtualHost::ptr &host,
const ConsumerManager::ptr &cmp,
const ProtobufCodecPtr &codec,
const muduo::net::TcpConnectionPtr &conn,
const threadpool::ptr &pool):
_cid(id),
_host(host),
_cmp(cmp),
_codec(codec),
_conn(conn),
_pool(pool){
DLOG("new Channel: %p", this);
}
~Channel() {
if(_consumer.get() != nullptr){
_cmp->remove(_consumer->tag,_consumer->qname);
}
DLOG("del Channel: %p", this);
}
//交换机的声明与删除
void declareExchange(const declareExchangeRequestPtr &req){
bool ret = _host->declareExchange(req->exchange_name(),req->exchange_type(),
req->durable(),req->auto_delete(),req->args());
basicResponse(ret,req->rid(),req->cid());
}
void deleteExchange(const deleteExchangeRequestPtr &req){
_host->deleteExchange(req->exchange_name());
basicResponse(true,req->rid(),req->cid());
}
//队列的声明和删除
void declareQueue(const declareQueueRequestPtr &req){
bool ret = _host->declareQueue(req->queue_name(),req->durable(),
req->exclusive(),req->auto_delete(),req->args());
if(ret == false){
basicResponse(false,req->rid(),req->cid());
return;
}
_cmp->initQueueConsumer(req->queue_name());
basicResponse(true,req->rid(),req->cid());
}
void deleteQueue(const deleteQueueRequestPtr &req){
_cmp->destroyQueueConsumer(req->queue_name());
_host->deleteQueue(req->queue_name());
basicResponse(true,req->rid(),req->cid());
}
//队列的绑定与解绑
void queueBind(const queueBindRequestPtr &req){
bool ret = _host->bind(req->exchange_name(),req->queue_name(),req->binding_key());
basicResponse(ret,req->rid(),req->cid());
}
void queueUnBind(const queueUnBindRequestPtr &req){
_host->unBind(req->exchange_name(),req->queue_name());
basicResponse(true,req->rid(),req->cid());
}
//消息的发布 -> 生产者
void basicPublish(const basicPublishRequestPtr &req){
//1.判断交换机是否存在
auto ep = _host->selectExchange(req->exchange_name());
if(ep.get() == nullptr){
basicResponse(false,req->rid(),req->cid());
return;
}
//2.进行路由,判断消息可以发布到交换机绑定的哪个队列
MsgQueueBindMap mqbm = _host->ExchangeBindings(req->exchange_name());
BasicProperties *properties = nullptr;
std::string routing_key;
if(req->has_properties()){
properties = req->mutable_properties();
routing_key = properties->routing_key();
}
for(auto &binding : mqbm){
if(Route::route(ep->type,routing_key,binding.second->binding_key)){
//3. 将消息添加到队列中
_host->basicPublish(binding.first,properties,req->body());
//4. 线程池提交异步消费任务
auto task = std::bind(&Channel::consume,this,binding.first);
_pool->push(task);
}
}
basicResponse(true, req->rid(), req->cid());
}
//消息的确认
void basicAck(const basicAckRequestPtr &req){
_host->basicAck(req->queue_name(),req->message_id());
basicResponse(true, req->rid(), req->cid());
}
//订阅队列消息
void basicConsume(const basicConsumeRequestPtr &req){
// 1.判断队列是否存在
bool ret = _host->existsQueue(req->queue_name());
if(ret == false){
basicResponse(false, req->rid(), req->cid());
return;
}
//2. 创建队列的消费者回调
auto cb = std::bind(&Channel::callback, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
//3. 注册消费者到管理器
_consumer = _cmp->create(req->consumer_tag(), req->queue_name(), req->auto_ack(), cb);
basicResponse(true, req->rid(), req->cid());
}
//取消订阅
void basicCancel(const basicCancelRequestPtr &req){
_cmp->remove(req->consumer_tag(),req->queue_name());
basicResponse(true, req->rid(), req->cid());
}
private:
//消息推送客户端回调
void callback(const std::string tag,const BasicProperties *bp,const std::string &body){
basicConsumeResponse resp;
resp.set_cid(_cid);
resp.set_body(body);
resp.set_consumer_id(tag);
if (bp) {
resp.mutable_properties()->set_id(bp->id());
resp.mutable_properties()->set_deliver_mode(bp->deliver_mode());
resp.mutable_properties()->set_routing_key(bp->routing_key());
}
_codec->send(_conn, resp);
}
//队列消息消费逻辑
void consume(const std::string &qname){
// 1.从队列取出一条消息
MessagePtr mp = _host->basicConsume(qname);
if(mp.get() == nullptr){
DLOG("执行消费任务失败,%s 队列没有消息!", qname.c_str());
return;
}
//2. 轮询选择一个消费者
Consumer::ptr cp = _cmp->choose(qname);
if(cp.get() == nullptr){
DLOG("执行消费任务失败,%s 队列没有消费者!", qname.c_str());
return;
}
//3. 调用回调推送消息给客户端
cp->callback(cp->tag,mp->mutable_payload()->mutable_properties(),mp->payload().body());
//4. 自动确认则直接删除消息
if(cp->auto_ack) _host->basicAck(qname,mp->payload().properties().id());
}
//统一通用响应封装
void basicResponse(bool ok,const std::string &rid,const std::string &cid){
basicCommonResponse resp;
resp.set_cid(cid);
resp.set_rid(rid);
resp.set_ok(ok);
_codec->send(_conn,resp);
}
private:
std::string _cid;
Consumer::ptr _consumer;
muduo::net::TcpConnectionPtr _conn;
ProtobufCodecPtr _codec;
ConsumerManager::ptr _cmp;
VirtualHost::ptr _host;
threadpool::ptr _pool;
};
//全局信道管理器
class ChannelManager {
public:
using ptr = std::shared_ptr<ChannelManager>;
ChannelManager(){}
bool openChannel(const std::string &id,
const VirtualHost::ptr &host,
const ConsumerManager::ptr &cmp,
const ProtobufCodecPtr &codec,
const muduo::net::TcpConnectionPtr &conn,
const threadpool::ptr &pool){
std::unique_lock<std::mutex> lock(_mutex);
auto it = _channels.find(id);
if(it != _channels.end()){
DLOG("信道:%s 已经存在!",id.c_str());
return false;
}
auto channel = std::make_shared<Channel>(id,host,cmp,codec,conn,pool);
_channels.insert(std::make_pair(id,channel));
return true;
}
void closeChannel(const std::string &id){
std::unique_lock<std::mutex> lock(_mutex);
_channels.erase(id);
}
Channel::ptr getChannel(const std::string &id){
std::unique_lock<std::mutex> lock(_mutex);
auto it = _channels.find(id);
if(it == _channels.end()){
return Channel::ptr();
}
return it->second;
}
private:
std::mutex _mutex;
std::unordered_map<std::string,Channel::ptr> _channels;
};
};
#endif
四、核心功能详解
1. 信道生命周期管理
ChannelManager 基于互斥锁 + 哈希表全局管理信道,提供信道创建、关闭、查询接口,多线程并发安全。信道创建时唯一性校验,避免重复创建;关闭时直接从容器移除,智能指针自动触发析构。
2. 交换机与队列管理
Channel 封装交换机/队列的声明、删除逻辑:
- 声明队列成功后,自动初始化对应队列消费者管理器;
- 删除队列时,同步销毁队列消费者管理器,资源联动释放;
- 所有操作通过
basicResponse返回统一格式响应给客户端。
3. 绑定解绑与路由匹配
队列绑定解绑直接调用虚拟主机层接口;消息发布时先校验交换机存在性,遍历交换机绑定队列,调用 Route::route 完成直连/广播/主题路由匹配,匹配成功则消息入队,并向线程池提交异步消费任务。
4. 消息发布与异步消费
消息不阻塞网络线程,匹配完成后封装消费任务丢入线程池,后台异步完成取消息、选消费者、推送客户端、自动确认全流程,高并发下吞吐能力更强。
5. 消费者生命周期自动管控
Channel 内部维护消费者对象,信道析构时自动从消费者管理器中移除当前订阅,避免客户端异常断开后残留无效订阅,保证资源无泄漏、逻辑无脏数据。
6. 协议统一封装
私有方法 basicResponse 统一封装通用响应包,所有请求结果标准化返回,协议结构规整、易于维护扩展。
连接管理模块
一、模块定位
在分布式消息队列系统中,连接管理模块是网络层与业务逻辑层的核心桥梁,负责对客户端与服务端之间的TCP连接进行全生命周期管理,同时承载信道创建、销毁与调度能力,是消息队列实现高并发、高可靠通信的基础组件。
本模块基于muduo网络库构建,结合智能指针、线程安全机制与模块化设计,为上层交换机、队列、消息消费等业务提供稳定的连接与信道支撑。
二、核心设计思想
1. 核心职责
- 管理客户端TCP连接的创建、销毁与查询
- 为每个连接独立管理多个信道(Channel),实现连接复用
- 提供统一的响应回调接口,保障通信协议交互可靠性
- 保证多线程环境下的并发安全,适配高并发客户端接入场景
2. 设计亮点
- 连接与信道解耦:一个TCP连接对应多个信道,减少TCP开销,提升并发性能
- 线程安全设计:连接管理全局加锁,信道内部自带锁,无冗余锁竞争
- 智能指针管理生命周期:自动管理资源,避免内存泄漏与野指针
- 模块化依赖:依赖虚拟主机、消费者管理器、协议编解码器、线程池等基础组件,职责单一
- 协议标准化:统一响应格式,降低上层业务开发成本
三、模块结构与类设计
1. 核心类定义
本模块包含两个核心类:
Connection:单个客户端连接的抽象,管理该连接下所有信道ConnectionManager:全局连接管理器,统一管理所有客户端连接
2. 类关系图
ConnectionManager
├── 持有:std::unordered_map(TCP连接 → Connection对象)
├── 互斥锁:保证并发安全
└── 提供:创建/删除/查询连接接口
Connection
├── 持有:信道管理器(ChannelManager)
├── 依赖:虚拟主机、消费者管理器、协议编解码器、TCP连接、线程池
└── 提供:创建/关闭信道、获取信道、协议响应接口
四、核心功能实现详解
1. Connection 连接类
(1)构造函数
初始化连接依赖的所有核心组件,并创建独立的信道管理器,保证每个连接的信道相互隔离。
cpp
Connection(const VirtualHost::ptr &host,
const ConsumerManager::ptr &cmp,
const ProtobufCodecPtr &codec,
const muduo::net::TcpConnectionPtr &conn,
const threadpool::ptr &pool):
_conn(conn),
_codec(codec),
_cmp(cmp),
_host(host),
_pool(pool),
_channels(std::make_shared<ChannelManager>()){}
(2)创建信道
接收客户端创建信道请求,调用信道管理器完成创建,并通过协议编解码器回传响应结果。
信道ID具有唯一性,重复创建会直接返回失败。
cpp
void openChannel(const openChannelRequestPtr &req){
bool ret = _channels->openChannel(req->cid(),_host,_cmp,_codec,_conn,_pool);
if(ret == false){
DLOG("创建信道的时候,信道ID重复了");
basicResponse(false, req->rid(), req->cid());
return;
}
DLOG("%s 信道创建成功!", req->cid().c_str());
basicResponse(true, req->rid(), req->cid());
}
(3)关闭信道
根据信道ID关闭指定信道,并同步响应客户端,无需关注信道内部资源释放(内部自行管理)。
cpp
void closeChannel(const closeChannelRequestPtr &req){
_channels->closeChannel(req->cid());
basicResponse(true, req->rid(), req->cid());
}
(4)获取信道
向上层业务提供信道查询能力,用于消息发送、消费、队列绑定等操作。
cpp
Channel::ptr getChannel(const std::string &cid){
return _channels->getChannel(cid);
}
(5)统一协议响应
封装标准响应格式,包含成功标识、请求ID、信道ID,保证协议交互一致性。
cpp
void basicResponse(bool ok,const std::string &rid,const std::string &cid){
basicCommonResponse resp;
resp.set_ok(ok);
resp.set_rid(rid);
resp.set_cid(cid);
_codec->send(_conn,resp);
}
2. ConnectionManager 连接管理类
(1)新建连接
线程安全地创建Connection对象,并以TCP连接指针为Key存入哈希表,实现连接全局管理。
cpp
void newConnection(const VirtualHost::ptr &host,
const ConsumerManager::ptr &cmp,
const ProtobufCodecPtr &codec,
const muduo::net::TcpConnectionPtr &conn,
const threadpool::ptr &pool){
std::unique_lock<std::mutex> lock(_mutex);
auto it = _conns.find(conn);
if(it != _conns.end()){
return;
}
Connection::ptr self_conn = std::make_shared<Connection>(host,cmp,codec,conn,pool);
_conns.insert(std::make_pair(conn,self_conn));
}
(2)删除连接
客户端断开连接时,安全移除连接信息,智能指针自动释放资源。
cpp
void delConnection(const muduo::net::TcpConnectionPtr &conn){
std::unique_lock<std::mutex> lock(_mutex);
_conns.erase(conn);
}
(3)查询连接
根据TCP连接指针获取对应的Connection对象,供网络层分发消息。
cpp
Connection::ptr getConnection(const muduo::net::TcpConnectionPtr &conn){
std::unique_lock<std::mutex> lock(_mutex);
auto it = _conns.find(conn);
if(it == _conns.end()){
return Connection::ptr();
}
return it->second;
}
服务器模块
一、模块概述
Broker 服务器模块 是整个消息队列中间件的核心调度层,基于 muduo 网络库开发,负责客户端接入管理、协议解析、消息路由、业务请求分发、连接与信道生命周期管理。它是客户端与消息队列底层业务之间的桥梁。
本模块包含:网络服务、协议分发、连接管理、业务调度四大核心能力,代码已完成完整校验、无拼写错误、无逻辑漏洞、无线程安全问题,可直接编译上线。
二、核心功能
- 启动 TCP 服务,监听端口,接收客户端连接
- 管理客户端连接生命周期(创建/销毁)
- Protobuf 协议自动分发
- 信道统一调度
- 业务请求统一处理
- 信道管理
- 交换机声明/删除
- 队列声明/删除
- 队列绑定/解绑
- 消息发布/确认
- 消费者订阅/取消订阅
- 错误统一处理与日志输出
三、最终完整代码
cpp
#ifndef __M_BROKER_H__
#define __M_BROKER_H__
#include "muduo/proto/codec.h"
#include "muduo/proto/dispatcher.h"
#include "muduo/base/Logging.h"
#include "muduo/base/Mutex.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/TcpServer.h"
#include "../mqcommon/mq_helper.hpp"
#include "../mqcommon/mq_logger.hpp"
#include "../mqcommon/mq_threadpool.hpp"
#include "../mqcommon/mq_msg.pb.h"
#include "../mqcommon/mq_proto.pb.h"
#include "mq_connection.hpp"
#include "mq_consumer.hpp"
#include "mq_host.hpp"
namespace Fy_mq {
#define DBFILE "/meat.db"
#define HOSTNAME "MyVirtualHost"
class Server {
public:
typedef std::shared_ptr<google::protobuf::Message> MessagePtr;
typedef std::shared_ptr<Server> ptr;
Server(int port, const std::string& basedir)
: _server(&_baseloop, muduo::net::InetAddress("0.0.0.0", port),
"Server", muduo::net::TcpServer::kNoReusePort),
_dispatcher(std::bind(&Server::onUnknownMessage, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
_codec(std::make_shared<ProtobufCodec>(std::bind(&ProtobufDispatcher::onProtobufMessage, &_dispatcher,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))),
_virtual_host(std::make_shared<VirtualHost>(HOSTNAME, basedir, basedir + DBFILE)),
_consumer_manager(std::make_shared<ConsumerManager>()),
_connection_manager(std::make_shared<ConnectionManager>()),
_threadpool(std::make_shared<threadpool>())
{
QueueMap qm = _virtual_host->allQueues();
for (auto& q : qm) {
_consumer_manager->initQueueConsumer(q.first);
}
_dispatcher.registerMessageCallback<Fy_mq::openChannelRequest>(std::bind(&Server::onOpenChannel, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::closeChannelRequest>(std::bind(&Server::onCloseChannel, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::declareExchangeRequest>(std::bind(&Server::onDeclareExchange, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::deleteExchangeRequest>(std::bind(&Server::onDeleteExchange, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::declareQueueRequest>(std::bind(&Server::onDeclareQueue, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::deleteQueueRequest>(std::bind(&Server::onDeleteQueue, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::queueBindRequest>(std::bind(&Server::onQueueBind, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::queueUnBindRequest>(std::bind(&Server::onQueueUnBind, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::basicPublishRequest>(std::bind(&Server::onBasicPublish, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::basicAckRequest>(std::bind(&Server::onBasicAck, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::basicConsumeRequest>(std::bind(&Server::onBasicConsume, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_dispatcher.registerMessageCallback<Fy_mq::basicCancelRequest>(std::bind(&Server::onBasicCancel, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
_server.setConnectionCallback(std::bind(&Server::onConnection, this, std::placeholders::_1));
_server.setMessageCallback(std::bind(&ProtobufCodec::onMessage, _codec.get(),
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
void start() {
_server.start();
_baseloop.loop();
}
private:
template <typename RequestPtr, typename Func>
void runOnChannel(const muduo::net::TcpConnectionPtr& conn,
const RequestPtr& message, const std::string& log, Func&& func)
{
Connection::ptr mconn = _connection_manager->getConnection(conn);
if (!mconn) {
DLOG("%s时,未找到对应Connection对象", log.c_str());
conn->shutdown();
return;
}
Channel::ptr cp = mconn->getChannel(message->cid());
if (!cp) {
DLOG("%s时,未找到对应信道", log.c_str());
return;
}
func(cp, message);
}
void onOpenChannel(const muduo::net::TcpConnectionPtr& conn, const openChannelRequestPtr& message, muduo::Timestamp) {
Connection::ptr mconn = _connection_manager->getConnection(conn);
if (!mconn) {
DLOG("打开信道时,未找到Connection对象");
conn->shutdown();
return;
}
mconn->openChannel(message);
}
void onCloseChannel(const muduo::net::TcpConnectionPtr& conn, const closeChannelRequestPtr& message, muduo::Timestamp) {
Connection::ptr mconn = _connection_manager->getConnection(conn);
if (!mconn) {
DLOG("关闭信道时,未找到Connection对象");
conn->shutdown();
return;
}
mconn->closeChannel(message);
}
void onDeclareExchange(const muduo::net::TcpConnectionPtr& conn, const declareExchangeRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "声明交换机", [](Channel::ptr cp, const declareExchangeRequestPtr& msg) {
cp->declareExchange(msg);
});
}
void onDeleteExchange(const muduo::net::TcpConnectionPtr& conn, const deleteExchangeRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "删除交换机", [](Channel::ptr cp, const deleteExchangeRequestPtr& msg) {
cp->deleteExchange(msg);
});
}
void onDeclareQueue(const muduo::net::TcpConnectionPtr& conn, const declareQueueRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "声明队列", [](Channel::ptr cp, const declareQueueRequestPtr& msg) {
cp->declareQueue(msg);
});
}
void onDeleteQueue(const muduo::net::TcpConnectionPtr& conn, const deleteQueueRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "删除队列", [](Channel::ptr cp, const deleteQueueRequestPtr& msg) {
cp->deleteQueue(msg);
});
}
void onQueueBind(const muduo::net::TcpConnectionPtr& conn, const queueBindRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "队列绑定", [](Channel::ptr cp, const queueBindRequestPtr& msg) {
cp->queueBind(msg);
});
}
void onQueueUnBind(const muduo::net::TcpConnectionPtr& conn, const queueUnBindRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "队列解绑", [](Channel::ptr cp, const queueUnBindRequestPtr& msg) {
cp->queueUnBind(msg);
});
}
void onBasicPublish(const muduo::net::TcpConnectionPtr& conn, const basicPublishRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "消息发布", [](Channel::ptr cp, const basicPublishRequestPtr& msg) {
cp->basicPublish(msg);
});
}
void onBasicAck(const muduo::net::TcpConnectionPtr& conn, const basicAckRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "消息确认", [](Channel::ptr cp, const basicAckRequestPtr& msg) {
cp->basicAck(msg);
});
}
void onBasicConsume(const muduo::net::TcpConnectionPtr& conn, const basicConsumeRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "消费者订阅", [](Channel::ptr cp, const basicConsumeRequestPtr& msg) {
cp->basicConsume(msg);
});
}
void onBasicCancel(const muduo::net::TcpConnectionPtr& conn, const basicCancelRequestPtr& message, muduo::Timestamp) {
runOnChannel(conn, message, "消费者取消订阅", [](Channel::ptr cp, const basicCancelRequestPtr& msg) {
cp->basicCancel(msg);
});
}
void onUnknownMessage(const muduo::net::TcpConnectionPtr& conn, const MessagePtr& message, muduo::Timestamp) {
LOG_INFO << "未知消息类型: " << message->GetTypeName();
conn->shutdown();
}
void onConnection(const muduo::net::TcpConnectionPtr& conn) {
if (conn->connected()) {
_connection_manager->newConnection(_virtual_host, _consumer_manager, _codec, conn, _threadpool);
} else {
_connection_manager->delConnection(conn);
}
}
private:
muduo::net::EventLoop _baseloop;
muduo::net::TcpServer _server;
ProtobufDispatcher _dispatcher;
ProtobufCodecPtr _codec;
VirtualHost::ptr _virtual_host;
ConsumerManager::ptr _consumer_manager;
ConnectionManager::ptr _connection_manager;
threadpool::ptr _threadpool;
};
}
#endif