从零实现Json-Rpc框架】- 项目实现 - 服务端registry&discovery实现

📢博客主页:https://blog.csdn.net/2301_779549673

📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

📢本文由 JohnKi 原创,首发于 CSDN🙉

📢未来很长,值得我们全力奔赴更美好的生活✨

文章目录


📢前言

前几篇文章中,笔者介绍了rpc的原理和目的,也介绍了需要使用的部分第三方库和我们所需实现的功能

现在我们着手项目实现篇章,目前零碎接口项目消息字段类型抽象层的封装 都已经完成了

截至上一篇文章,我们已经完成了 rpc框架 的实现

接下来我们将对 服务端registry & discovery 进行实现,让其能够更加便捷


🏳️‍🌈一、重新理一遍思路

说实话,到这里笔者的脑子已经不清醒了,每个模块在实现的时候都很明白,放在一起就特别的困惑,所以这里再回顾一遍这个 rpc框架 的整个逻辑

1.1 首先,是最基本的三个前置块

1.2 抽象层子类的细分

这部分至关重要,它将整个框架分开来,使得 客户端服务端 能够凭借着 缓冲区、连接、协议 串联起来,真正实现通信,但此时,通信模式仅仅是 一对一

所以就需要一个 dispatcher 作为中间的转承,使得多对多的模式实现

1.3 dispatcher 分发转承中心


dispatcher 的两个最大的功能

  1. 找到消息类型对应的业务处理函数,并调用
  2. 关联消息类型和消息处理方法,并存储

这里提示一下

  1. rcp 中的服务 service 是指这个框架所能提供的服务,也就是那些回调函数所整合的功能
  2. 而服务端,是指 各个具有处理各种消息功能的函数(主机) 的集合

1.4 服务端

首先是 rpc_route.hpp 这部分,通过模块化设计,实现了 RPC 服务端核心功能,包括服务注册、参数校验、请求路由和线程安全管理。

然后就是这篇要实现的 rcp_registry.hpp ,这段代码通过分层设计实现了服务注册与发现 的核心功能

最后是一整个 服务端 逻辑,也就是 rcp_server.hpp 通过消息协议和 Dispatcher 实现松耦合交互,构建灵活可扩展的 RPC 框架

1.5 客户端

🏳️‍🌈二、服务端注册类实现

2.1 核心设计目标

该类用于管理分布式系统中的服务提供者(Provider),核心功能包括:

  1. 服务注册:新服务提供者上线时注册方法与连接信息。
  2. 服务发现:根据方法名查询可用的服务提供者地址。
  3. 生命周期管理:处理服务提供者的上下线,维护提供者-连接映射关系。
  4. 线程安全:通过互斥锁保护共享数据结构的并发访问。

2.2 成员变量

先来看看他的变量都有哪些

2.3 服务提供信息结构

我们所需要创建的是一个 服务提供者对象 ,他需要提供一些能够解决 来自客户端的请求 的方法

因为一个 服务提供者对象 是不仅仅只有一种方法能够提供的,所以我们可以通过一个 vector 来管理

所以就需要有

  • 方法
  • 连接
  • 地址
bash 复制代码
// 服务提供者信息
struct Provider {
    using ptr = std::shared_ptr<Provider>;
    std::mutex _mutex;
    BaseConnection::ptr conn;
    Address host;
    std::vector<std::string> methods;
    Provider(const BaseConnection::ptr& c, const Address& h)
        : conn(c), host(h) {}
    void appendMethod(const std::string& method) {
        std::unique_lock<std::mutex> lock(_mutex);
        methods.emplace_back(method);
    }
};

2.4 关键方法

  1. addProvider() - 服务注册
bash 复制代码
void addProvider(const BaseConnection::ptr& c, const Address& h, const std::string& method)

功能 :当服务提供者注册新方法时调用,将方法与连接关联。
​流程

  • 查找或创建 Provider:通过连接 c 在 _conns 中查找现有 Provider,若不存在则创建并绑定连接。
  • 更新方法列表:将方法 method 添加到 Provider 的方法列表,并将该 Provider 注入 _providers[method] 的集合。
  1. getProvider() - 查询连接对应 Provider
bash 复制代码
Provider::ptr getProvider(const BaseConnection::ptr& c)

功能 :通过连接对象获取对应的 Provider。
​特点:短时加锁,快速返回结果,降低锁竞争。

​3. deleteProvider() - 服务下线

bash 复制代码
void deleteProvider(const BaseConnection::ptr& c)

功能 :移除断开连接的服务提供者,清理相关资源。
​流程

  • 移除方法关联:遍历 Provider 的方法,从 _providers 的对应集合中删除该 Provider。
  • 删除连接记录:从 _conns 中移除连接。

​4. methodHosts() - 查询方法提供者地址

bash 复制代码
std::vector<Address> methodHosts(const std::string& method)

功能 :根据方法名获取所有可用提供者的地址。
​逻辑 :遍历 _providers[method] 集合,收集地址。
​异常处理:方法不存在时记录日志并返回空列表。

2.5 整体代码

bash 复制代码
// 管理服务提供者(Provider),处理注册、注销,维护服务-提供者映射。
        class ProviderManager{
            public:
                using ptr = std::shared_ptr<ProviderManager>;

                // 服务提供者信息
                struct Provider{
                    using ptr = std::shared_ptr<Provider>;
                    std::mutex _mutex;
                    BaseConnection::ptr conn;
                    Address host;
                    std::vector<std::string> methods;
                    Provider(const BaseConnection::ptr& c, const Address& h)
                        : conn(c), 
                          host(h) 
                    {}
                    void appendMethod(const std::string& method){
                        std::unique_lock<std::mutex> lock(_mutex);
                        methods.emplace_back(method);
                    }
                };

                // 当一个新的服务提供者进行服务注册的时候调用
                void addProvider(const BaseConnection::ptr& c, const Address& h, const std::string& method){
                    Provider::ptr provider;
                    // 查找连接所关联的服务提供者对象,找到则获取,找不到则创建,并建立关联
                        // 限制作用域,限制 加锁 的周期
                    {   
                        std::unique_lock<std::mutex> lock(_mutex);
                        auto it = _conns.find(c);
                        if(it != _conns.end())  provider = it->second;
                        else{
                            provider = std::make_shared<Provider>(c, h);
                            _conns.insert(std::make_pair(c, provider));
                        }
                        // method方法的提供主机要多出一个, _providers新增数据
                            // 1. 获取该 mehod 的提供主机的 set,通过取地址得到
                            // 2. 向 set 中插入 provider
                        auto& providers = _providers[method];
                        providers.insert(provider);
                    }
                    // 向服务对象中新增一个锁能提供的服务名称
                    provider->appendMethod(method);
                }

                // 当一个服务提供者断开连接的时候,获取它的信息,用于进行服务下线通知
                Provider::ptr getProvider(const BaseConnection::ptr& c){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _conns.find(c);
                    if(it != _conns.end()) return it->second;
                    return Provider::ptr();
                }

                // 当一个服务提供者断开连接的时候,在提供者列表中删除它的信息
                void deleteProvider(const BaseConnection::ptr& c){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _conns.find(c);
                    if(it != _conns.end()){ 
                        auto& provider = it->second;
                        // 遍历该提供者提供的服务,从 _providers 中删除该提供者
                        for(auto& method : it->second->methods){
                            auto& providers = _providers[method];
                            providers.erase(provider);
                        }
                    } 
                    _conns.erase(it);
                }

                std::vector<Address> methodHosts(const std::string& method){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _providers.find(method);
                    if(it == _providers.end()){
                        ELOG("methodHosts 找不到该方法的提供主机!");
                        return std::vector<Address>();
                    }
                    std::vector<Address> result;
                    for (auto &provider : it->second) {
                        result.push_back(provider->host);
                    }
                    return result;
                }

            private:
                std::mutex _mutex;
                std::unordered_map<std::string, std::set<Provider::ptr>> _providers;    // 方法名 → 提供者列表
                std::unordered_map<BaseConnection::ptr, Provider::ptr> _conns;          // 连接 → 提供者
        };  

🏳️‍🌈三、服务端发现实现

3.1 核心设计目标

该类用于管理分布式系统中的服务发现者(Discoverer),核心功能包括:

  • 服务订阅管理:记录客户端关注的服务方法。
  • 上下线通知:向订阅者推送服务提供者的上下线事件。
  • 生命周期维护:处理发现者的连接状态与资源清理。
  • 线程安全:通过互斥锁保护共享数据结构的并发访问。

3.2 关键成员变量

3.3 核心接口分析

  1. addDiscoverer() - 订阅服务
bash 复制代码
Discoverer::ptr addDiscoverer(const BaseConnection::ptr& c, const std::string& method)

功能 :为客户端新增服务订阅,记录方法名并关联连接。
​流程

  • 查找或创建 Discoverer:通过连接 c 在 _conns 中查找现有发现者,若不存在则创建并绑定连接。
  • 更新订阅列表:将方法 method 添加到发现者的订阅列表,并将该发现者注入 _discoverers[method] 的集合。
  1. deleteDiscoverer() - 取消订阅
bash 复制代码
void deleteDiscoverer(const BaseConnection::ptr& c)

功能 :移除客户端连接及其订阅信息。
​流程

  • 清理方法关联:遍历发现者的订阅方法,从 _discoverers 的对应集合中删除该发现者。
  • 删除连接记录:从 _conns 中移除连接。

​优点:锁覆盖完整操作,避免中间状态不一致。

  1. onlineNotify()/offlineNotify() - 上下线通知
bash 复制代码
void onlineNotify(const std::string& method, const Address& host)
void offlineNotify(const std::string& method, const Address &host)

功能 :向所有订阅某方法的客户端推送服务提供者的上下线事件。
​逻辑:调用私有 notify() 函数构造消息并广播。

3.4 整体代码

bash 复制代码
// 管理服务发现者(Discoverer),记录客户端关注的服务,处理上下线通知。
        class DiscovererManager{
            public:
                using ptr = std::shared_ptr<DiscovererManager>;

                // 发现者信息
                struct Discoverer{ 
                    using ptr = std::shared_ptr<Discoverer>;
                    std::mutex _mutex;
                    BaseConnection::ptr conn;                   // 发现者关联的客户端连接
                    std::vector<std::string> methods;           // 发现过的服务名称
                    Discoverer(const BaseConnection::ptr& c)
                        : conn(c) 
                    {}
                    void appendMethod(const std::string& method){
                        std::unique_lock<std::mutex> lcok(_mutex);
                        methods.emplace_back(method);
                    }
                };

                // 增
                // 当每次客户端进行服务发现的时候新增发现者,新增服务名称
                Discoverer::ptr addDiscoverer(const BaseConnection::ptr& c, const std::string& method){
                    Discoverer::ptr discoverer;
                    {
                        std::unique_lock<std::mutex> lock(_mutex);
                        auto it = _conns.find(c);
                        if(it != _conns.end())
                            discoverer = it->second;
                        else{
                            discoverer = std::make_shared<Discoverer>(c);
                            _conns.insert(std::make_pair(c, discoverer));
                        }
                        auto& discoverers = _discoverers[method];
                        discoverers.insert(discoverer);
                    }
                    discoverer->appendMethod(method);
                    return discoverer;
                } 

                // 删
                // 当放现在客户端断开连接时,找到发现者信息,删除关联数据
                void deleteDiscoverer(const BaseConnection::ptr& c){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _conns.find(c);
                    if(it != _conns.end()){
                        Discoverer::ptr discoverer = it->second;
                        for(auto& method : it->second->methods){
                            auto& discoverers = _discoverers[method];
                            discoverers.erase(discoverer);
                        }
                    }
                    _conns.erase(it);
                }

                // 通知
                // 当有一个新的服务提供者上线,则进行上线通知
                void onlineNotify(const std::string& method, const Address& host){
                    return notify(method, host, ServiceOptype::SERVICE_ONLINE);
                }

                // 当一个服务提供者断开连接的时候,进行下线通知
                void offlineNotify(const std::string& method, const Address &host){
                    return notify(method, Address(), ServiceOptype::SERVICE_OFFLINE);
                }

            private:
                void notify(const std::string& method, const Address& host, ServiceOptype optype){
                    std::unique_lock<std::mutex> _lock(_mutex);
                    auto it = _discoverers.find(method);
                    if(it == _discoverers.end()) return;

                    auto msg_req = MessageFactory::create<ServiceRequest>();
                    msg_req->setId(UUID::uuid());
                    msg_req->setMType(MType::REQ_SERVICE);
                    msg_req->setMethod(method);
                    msg_req->setHost(host);
                    msg_req->setServiceOptype(optype);

                    for(auto& discoverer : it->second)
                        discoverer->conn->send(msg_req);
                }

            private:
                std::mutex _mutex;
                std::unordered_map<std::string, std::set<Discoverer::ptr>> _discoverers;    // 方法名 → 发现者列表
                std::unordered_map<BaseConnection::ptr, Discoverer::ptr> _conns;            // 连接 → 发现者
        };

🏳️‍🌈四、服务端整合

4.1 核心设计目标

该类作为服务协调中枢,核心功能包括:

  • 请求分发:根据客户端请求类型(注册/发现)分派到对应管理器。
  • 生命周期联动:服务提供者上下线时,同步更新发现者订阅状态。
  • 响应封装:统一构建服务端响应消息,保障通信协议一致性。

4.2 关键接口分析

  1. onServiceRequest() - 请求入口
bash 复制代码
void onServiceRequest(const BaseConnection::ptr& conn, const ServiceRequest::ptr& msg)

功能 :处理客户端服务请求,分为注册与发现两种逻辑分支。
​流程

  • 注册分支:调用 _providers->addProvider() 注册服务提供者,并触发 _discoverers->onlineNotify() 通知订阅者。
  • 发现分支:调用 _discoverers->addDiscoverer() 记录订阅关系,并返回当前服务地址列表。
  1. onConnShutdown() - 连接关闭处理
bash 复制代码
void onConnShutdown(const BaseConnection::ptr& conn)

功能 :清理连接相关的服务提供者和发现者。
​流程

  • 从 _providers 获取提供者,遍历其方法调用 _discoverers->offlineNotify() 下线服务
  • 删除提供者和发现者记录。
    ​优点:保证服务上下线状态的一致性。

整体代码

bash 复制代码
// 协调服务提供者与发现者,处理服务请求和连接事件
class ProviderDiscovererManager {
public:
    using ptr = std::shared_ptr<ProviderDiscovererManager>;

    ProviderDiscovererManager()
        : _providers(std::make_shared<ProviderManager>()),
          _discoverers(std::make_shared<DiscovererManager>()) {}

    // 处理客户端服务发现请求
    void onServiceRequest(const BaseConnection::ptr& conn,
                          const ServiceRequest::ptr& msg) {
        // 服务操作请求:服务注册/服务发现
        ServiceOptype optype = msg->Serviceoptype();
        // 服务注册
        if (optype == ServiceOptype::SERVICE_REGISTRY) {
            ILOG("%s:%d 注册服务 %s", msg->host().first.c_str(),
                 msg->host().second, msg->method().c_str());
            // 1. 新增服务提供者
            _providers->addProvider(conn, msg->host(), msg->method());
            // 2. 进行服务上线的通知
            _discoverers->onlineNotify(msg->method(), msg->host());
            // 3. 响应服务注册成功
            registryResponse(conn, msg);
        }
        // 服务发现:`
        else if (optype == ServiceOptype::SERVICE_DISCOVERY) {
            // 1. 新增服务发现者
            _discoverers->addDiscoverer(conn, msg->method());
            discoveryResponse(conn, msg);
        } else {
            ELOG("收到服务操作请求,但是操作类型错误!");
            errorResponse(conn, msg);
        }
    }

    // 服务提供者 断开连接
    void onConnShutdown(const BaseConnection::ptr& conn) {
        auto provider = _providers->getProvider(conn);
        if (provider.get() != nullptr) {
            for (auto& method : provider->methods) {
                _discoverers->offlineNotify(method, provider->host);
            }
            _providers->deleteProvider(conn);
        }
        _discoverers->deleteDiscoverer(conn);
    }

private:
    // 响应服务注册
    void registryResponse(const BaseConnection::ptr& conn,
                          const ServiceRequest::ptr& msg) {
        auto msg_rsp = MessageFactory::create<ServiceResponse>();
        msg_rsp->setId(msg->rid());
        msg_rsp->setMType(MType::RSP_SERVICE);
        msg_rsp->setRcode(RCode::RCODE_OK);
        msg_rsp->setOptype(ServiceOptype::SERVICE_REGISTRY);
        conn->send(msg_rsp);
    }

    // 响应服务发现
    void discoveryResponse(const BaseConnection::ptr& conn,
                           const ServiceRequest::ptr& msg) {
        auto msg_rsp = MessageFactory::create<ServiceResponse>();

        std::vector<Address> hosts = _providers->methodHosts(msg->method());

        msg_rsp->setId(msg->rid());
        msg_rsp->setMType(MType::RSP_SERVICE);
        if (hosts.empty()) {
            msg_rsp->setRcode(RCode::RCODE_NOT_FOUND_SERVICE);
            conn->send(msg_rsp);
        } else {
            msg_rsp->setRcode(RCode::RCODE_OK);
            msg_rsp->setOptype(ServiceOptype::SERVICE_REGISTRY);
            msg_rsp->setMethod(msg->method());
            msg_rsp->setHost(hosts);
            conn->send(msg_rsp);
        }
    }

    // 响应错误请求
    void errorResponse(const BaseConnection::ptr& conn,
                       const ServiceRequest::ptr& msg) {
        auto msg_rsp = MessageFactory::create<ServiceResponse>();
        msg_rsp->setId(msg->rid());
        msg_rsp->setMType(MType::RSP_SERVICE);
        msg_rsp->setRcode(RCode::RCODE_INVALID_OPTYPE);
        msg_rsp->setOptype(ServiceOptype::SERVICE_UNKNOW);
        conn->send(msg_rsp);
    }

private:
    ProviderManager::ptr _providers; // 提供者列表
    DiscovererManager::ptr _discoverers;
};

🏳️‍🌈四、服务端registry&discovery整体代码

bash 复制代码
#pragma once
#include "../common/net.hpp"
#include "../common/message.hpp"
#include <set>

namespace rpc{
    namespace server{

        // 管理服务提供者(Provider),处理注册、注销,维护服务-提供者映射。
        class ProviderManager{
            public:
                using ptr = std::shared_ptr<ProviderManager>;

                // 服务提供者信息
                struct Provider{
                    using ptr = std::shared_ptr<Provider>;
                    std::mutex _mutex;
                    BaseConnection::ptr conn;
                    Address host;
                    std::vector<std::string> methods;
                    Provider(const BaseConnection::ptr& c, const Address& h)
                        : conn(c), host(h) {}
                    void appendMethod(const std::string& method){
                        std::unique_lock<std::mutex> lock(_mutex);
                        methods.emplace_back(method);
                    }
                };

                // 当一个新的服务提供者进行服务注册的时候调用
                void addProvider(const BaseConnection::ptr& c, const Address& h, const std::string& method){
                    Provider::ptr provider;
                    // 查找连接所关联的服务提供者对象,找到则获取,找不到则创建,并建立关联
                        // 限制作用域,限制 加锁 的周期
                    {   
                        std::unique_lock<std::mutex> lock(_mutex);
                        auto it = _conns.find(c);
                        if(it != _conns.end())  provider = it->second;
                        else{
                            provider = std::make_shared<Provider>(c, h);
                            _conns.insert(std::make_pair(c, provider));
                        }
                        // method方法的提供主机要多出一个, _providers新增数据
                            // 1. 获取该 mehod 的提供主机的 set,通过取地址得到
                            // 2. 向 set 中插入 provider
                        auto& providers = _providers[method];
                        providers.insert(provider);
                    }
                    // 向服务对象中新增一个锁能提供的服务名称
                    provider->appendMethod(method);
                }

                // 当一个服务提供者断开连接的时候,获取它的信息,用于进行服务下线通知
                Provider::ptr getProvider(const BaseConnection::ptr& c){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _conns.find(c);
                    if(it != _conns.end()) return it->second;
                    return Provider::ptr();
                }

                // 当一个服务提供者断开连接的时候,在提供者列表中删除它的信息
                void deleteProvider(const BaseConnection::ptr& c){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _conns.find(c);
                    if(it != _conns.end()){ 
                        auto& provider = it->second;
                        // 遍历该提供者提供的服务,从 _providers 中删除该提供者
                        for(auto& method : it->second->methods){
                            auto& providers = _providers[method];
                            providers.erase(provider);
                        }
                    } 
                    _conns.erase(it);
                }

                // 查询方法提供者地址
                std::vector<Address> methodHosts(const std::string& method){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _providers.find(method);
                    if(it == _providers.end()){
                        ELOG("methodHosts 找不到该方法的提供主机!");
                        return std::vector<Address>();
                    }
                    std::vector<Address> result;
                    for (auto &provider : it->second) {
                        result.push_back(provider->host);
                    }
                    return result;
                }

            private:
                std::mutex _mutex;
                std::unordered_map<std::string, std::set<Provider::ptr>> _providers;    // 方法名 → 提供者列表
                std::unordered_map<BaseConnection::ptr, Provider::ptr> _conns;          // 连接 → 提供者
        };  

        // 管理服务发现者(Discoverer),记录客户端关注的服务,处理上下线通知。
        class DiscovererManager{
            public:
                using ptr = std::shared_ptr<DiscovererManager>;

                // 发现者信息
                struct Discoverer{ 
                    using ptr = std::shared_ptr<Discoverer>;
                    std::mutex _mutex;
                    BaseConnection::ptr conn;                   // 发现者关联的客户端连接
                    std::vector<std::string> methods;           // 发现过的服务名称
                    Discoverer(const BaseConnection::ptr& c)
                        : conn(c) 
                    {}
                    void appendMethod(const std::string& method){
                        std::unique_lock<std::mutex> lcok(_mutex);
                        methods.emplace_back(method);
                    }
                };

                // 增
                // 当每次客户端进行服务发现的时候新增发现者,新增服务名称
                Discoverer::ptr addDiscoverer(const BaseConnection::ptr& c, const std::string& method){
                    Discoverer::ptr discoverer;
                    {
                        std::unique_lock<std::mutex> lock(_mutex);
                        auto it = _conns.find(c);
                        if(it != _conns.end())
                            discoverer = it->second;
                        else{
                            discoverer = std::make_shared<Discoverer>(c);
                            _conns.insert(std::make_pair(c, discoverer));
                        }
                        auto& discoverers = _discoverers[method];
                        discoverers.insert(discoverer);
                    }
                    discoverer->appendMethod(method);
                    return discoverer;
                } 

                // 删
                // 当放现在客户端断开连接时,找到发现者信息,删除关联数据
                void deleteDiscoverer(const BaseConnection::ptr& c){
                    std::unique_lock<std::mutex> lock(_mutex);
                    auto it = _conns.find(c);
                    if(it != _conns.end()){
                        Discoverer::ptr discoverer = it->second;
                        for(auto& method : it->second->methods){
                            auto& discoverers = _discoverers[method];
                            discoverers.erase(discoverer);
                        }
                    }
                    _conns.erase(it);
                }

                // 通知
                // 当有一个新的服务提供者上线,则进行上线通知
                void onlineNotify(const std::string& method, const Address& host){
                    return notify(method, host, ServiceOptype::SERVICE_ONLINE);
                }

                // 当一个服务提供者断开连接的时候,进行下线通知
                void offlineNotify(const std::string& method, const Address &host){
                    return notify(method, Address(), ServiceOptype::SERVICE_OFFLINE);
                }

            private:
                void notify(const std::string& method, const Address& host, ServiceOptype optype){
                    std::unique_lock<std::mutex> _lock(_mutex);
                    auto it = _discoverers.find(method);
                    if(it == _discoverers.end()) return;

                    auto msg_req = MessageFactory::create<ServiceRequest>();
                    msg_req->setId(UUID::uuid());
                    msg_req->setMType(MType::REQ_SERVICE);
                    msg_req->setMethod(method);
                    msg_req->setHost(host);
                    msg_req->setServiceOptype(optype);

                    for(auto& discoverer : it->second)
                        discoverer->conn->send(msg_req);
                }

            private:
                std::mutex _mutex;
                std::unordered_map<std::string, std::set<Discoverer::ptr>> _discoverers;    // 方法名 → 发现者列表
                std::unordered_map<BaseConnection::ptr, Discoverer::ptr> _conns;            // 连接 → 发现者
        };

        // 协调服务提供者与发现者,处理服务请求和连接事件
        class ProviderDiscovererManager{
            public:
                using ptr = std::shared_ptr<ProviderDiscovererManager>;

                ProviderDiscovererManager()
                    : _providers(std::make_shared<ProviderManager>()),
                      _discoverers(std::make_shared<DiscovererManager>())
                {}

                // 处理客户端服务发现请求
                void onServiceRequest(const BaseConnection::ptr& conn, const ServiceRequest::ptr& msg){
                    // 服务操作请求:服务注册/服务发现
                    ServiceOptype optype = msg->Serviceoptype();
                    // 服务注册
                    if(optype == ServiceOptype::SERVICE_REGISTRY){
                        ILOG("%s:%d 注册服务 %s", msg->host().first.c_str(), msg->host().second, msg->method().c_str());
                        // 1. 新增服务提供者
                        _providers->addProvider(conn, msg->host(), msg->method());
                        // 2. 进行服务上线的通知
                        _discoverers->onlineNotify(msg->method(), msg->host());
                        // 3. 响应服务注册成功
                        registryResponse(conn, msg);
                    }
                    // 服务发现:`
                    else if(optype == ServiceOptype::SERVICE_DISCOVERY){
                        // 1. 新增服务发现者
                        _discoverers->addDiscoverer(conn, msg->method());
                        discoveryResponse(conn, msg);
                    }
                    else{
                        ELOG("收到服务操作请求,但是操作类型错误!");
                        errorResponse(conn, msg);
                    }
                }

                // 服务提供者 断开连接
                void onConnShutdown(const BaseConnection::ptr& conn){
                    auto provider = _providers->getProvider(conn);
                    if(provider.get() != nullptr){
                        for(auto& method : provider->methods){
                            _discoverers->offlineNotify(method, provider->host);
                        }
                        _providers->deleteProvider(conn);
                    }
                    _discoverers->deleteDiscoverer(conn);
                }

            private:
                // 响应服务注册
                void registryResponse(const BaseConnection::ptr& conn, const ServiceRequest::ptr& msg){
                    auto msg_rsp = MessageFactory::create<ServiceResponse>();
                    msg_rsp->setId(msg->rid());
                    msg_rsp->setMType(MType::RSP_SERVICE);
                    msg_rsp->setRcode(RCode::RCODE_OK);
                    msg_rsp->setOptype(ServiceOptype::SERVICE_REGISTRY);
                    conn->send(msg_rsp);
                }

                // 响应服务发现
                void discoveryResponse(const BaseConnection::ptr& conn, const ServiceRequest::ptr& msg){
                    auto msg_rsp = MessageFactory::create<ServiceResponse>();
                    
                    std::vector<Address> hosts = _providers->methodHosts(msg->method());

                    msg_rsp->setId(msg->rid());
                    msg_rsp->setMType(MType::RSP_SERVICE);
                    if(hosts.empty()){
                        msg_rsp->setRcode(RCode::RCODE_NOT_FOUND_SERVICE);
                        conn->send(msg_rsp);
                    }
                    else{
                        msg_rsp->setRcode(RCode::RCODE_OK);
                        msg_rsp->setOptype(ServiceOptype::SERVICE_REGISTRY);
                        msg_rsp->setMethod(msg->method());
                        msg_rsp->setHost(hosts);
                        conn->send(msg_rsp);
                    } 
                }

                // 响应错误请求
                void errorResponse(const BaseConnection::ptr& conn, const ServiceRequest::ptr& msg){
                    auto msg_rsp = MessageFactory::create<ServiceResponse>();
                    msg_rsp->setId(msg->rid());
                    msg_rsp->setMType(MType::RSP_SERVICE);
                    msg_rsp->setRcode(RCode::RCODE_INVALID_OPTYPE);
                    msg_rsp->setOptype(ServiceOptype::SERVICE_UNKNOW);
                    conn->send(msg_rsp);
                }
            private:
                ProviderManager::ptr _providers;        // 提供者列表
                DiscovererManager::ptr _discoverers;
        };
    }
}

👥总结

本篇博文对 从零实现Json-Rpc框架】- 项目实现 - 服务端registry&discovery实现 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

相关推荐
暴走的YH12 分钟前
【网络协议】三次握手与四次挥手
网络·网络协议
仙女很美哦1 小时前
Flutter视频播放、Flutter VideoPlayer 视频播放组件精要
websocket·网络协议·tcp/ip·http·网络安全·https·udp
路由侠内网穿透2 小时前
本地部署开源流处理框架 Apache Flink 并实现外部访问
大数据·网络协议·tcp/ip·flink·服务发现·apache·consul
Amos_ FAT2 小时前
关于串口协议的一点知识
经验分享·网络协议
小吃饱了2 小时前
TCP可靠性传输
网络·网络协议·tcp/ip
q567315232 小时前
使用puppeteer库编写的爬虫程序
爬虫·python·网络协议·http
努力搬砖的咸鱼3 小时前
Qt中的数据解析--XML与JSON处理全攻略
xml·开发语言·qt·json
Zfox_3 小时前
【C++项目】从零实现RPC框架「四」:业务层实现与项目使用
linux·开发语言·c++·rpc·项目
前端极客探险家4 小时前
WebSocket 详解:构建一个复杂的实时聊天应用
网络·websocket·网络协议
iOS技术狂热者6 小时前
Flutter 音视频播放器与弹幕系统开发实践
websocket·网络协议·tcp/ip·http·网络安全·https·udp