仿RabbitMQ实现消息队列-服务端核心模块实现(5)

信道管理模块

一、模块概述

信道模块是自研消息队列的会话层核心组件,基于 Muduo 网络库与 Protobuf 协议实现,作为客户端与服务端交互的唯一桥梁。负责接收并处理客户端全部业务请求:交换机声明删除、队列声明删除、队列绑定解绑、消息发布、消息确认、消费者订阅与取消订阅。

采用 Channel + ChannelManager 双层架构:

  • Channel:单客户端会话信道,封装连接、协议编解码、消费者、虚拟主机、线程池等上下文;
  • ChannelManager:全局信道管理器,统一维护所有信道生命周期,保证并发线程安全。

模块依托路由匹配、消费者管理、虚拟主机、线程池等底层模块,实现协议解析、路由转发、消息入队、异步推送、资源自动回收全链路能力,适配高并发多客户端接入场景。

二、核心架构与依赖

1. 架构分层

  1. Channel:业务逻辑载体,处理单条连接的所有 MQ 协议请求;
  2. ChannelManager:全局信道容器,线程安全管理信道创建、销毁、查找;
  3. 底层依赖:虚拟主机、消费者管理器、路由匹配模块、线程池、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. 设计亮点

  1. 连接与信道解耦:一个TCP连接对应多个信道,减少TCP开销,提升并发性能
  2. 线程安全设计:连接管理全局加锁,信道内部自带锁,无冗余锁竞争
  3. 智能指针管理生命周期:自动管理资源,避免内存泄漏与野指针
  4. 模块化依赖:依赖虚拟主机、消费者管理器、协议编解码器、线程池等基础组件,职责单一
  5. 协议标准化:统一响应格式,降低上层业务开发成本

三、模块结构与类设计

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 网络库开发,负责客户端接入管理、协议解析、消息路由、业务请求分发、连接与信道生命周期管理。它是客户端与消息队列底层业务之间的桥梁。

本模块包含:网络服务、协议分发、连接管理、业务调度四大核心能力,代码已完成完整校验、无拼写错误、无逻辑漏洞、无线程安全问题,可直接编译上线。


二、核心功能

  1. 启动 TCP 服务,监听端口,接收客户端连接
  2. 管理客户端连接生命周期(创建/销毁)
  3. Protobuf 协议自动分发
  4. 信道统一调度
  5. 业务请求统一处理
    • 信道管理
    • 交换机声明/删除
    • 队列声明/删除
    • 队列绑定/解绑
    • 消息发布/确认
    • 消费者订阅/取消订阅
  6. 错误统一处理与日志输出

三、最终完整代码

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
相关推荐
Lyyaoo.2 小时前
Redis实现分布式锁
数据库·redis·分布式
KmSH8umpK12 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第八篇
数据库·redis·分布式
KmSH8umpK15 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第七篇
数据库·redis·分布式
_F_y20 小时前
仿RabbitMQ实现消息队列-服务端核心模块实现(4)
分布式·rabbitmq
Albert Edison1 天前
【RabbitMQ】发布确认模式(使用案例)
分布式·rabbitmq·ruby
EXnf1SbYK1 天前
Redis分布式锁进阶第十二篇:全系列终极兜底复盘 + 锁架构巡检落地 + 线上零事故收尾方案
redis·分布式·架构
EXnf1SbYK1 天前
Redis分布式锁进阶第八篇:锁超时乱序深度踩坑 + 看门狗失效真实溯源 + 业务长耗时标准化兜底方案
数据库·redis·分布式
EXnf1SbYK1 天前
Redis分布式锁进阶第十一篇
数据库·redis·分布式
biyezuopinvip1 天前
分布式风电场低电压穿越故障建模与仿真
分布式·matlab·毕业设计·毕业论文·分布式风电场·低电压穿越故障·建模与仿真