📢博客主页:https://blog.csdn.net/2301_779549673
📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨


文章目录
- 📢前言
- 🏳️🌈一、重新理一遍思路
-
- [1.1 首先,是最基本的三个前置块](#1.1 首先,是最基本的三个前置块)
- [1.2 抽象层子类的细分](#1.2 抽象层子类的细分)
- [1.3 dispatcher 分发转承中心](#1.3 dispatcher 分发转承中心)
- [1.4 服务端](#1.4 服务端)
- [1.5 客户端](#1.5 客户端)
- 🏳️🌈二、服务端注册类实现
-
- [2.1 核心设计目标](#2.1 核心设计目标)
- [2.2 成员变量](#2.2 成员变量)
- [2.3 服务提供信息结构](#2.3 服务提供信息结构)
- [2.4 关键方法](#2.4 关键方法)
- [2.5 整体代码](#2.5 整体代码)
- 🏳️🌈三、服务端发现实现
-
- [3.1 核心设计目标](#3.1 核心设计目标)
- [3.2 关键成员变量](#3.2 关键成员变量)
- [3.3 核心接口分析](#3.3 核心接口分析)
- [3.4 整体代码](#3.4 整体代码)
- 🏳️🌈四、服务端整合
-
- [4.1 核心设计目标](#4.1 核心设计目标)
- [4.2 关键接口分析](#4.2 关键接口分析)
- 整体代码
- 🏳️🌈四、服务端registry&discovery整体代码
- 👥总结
📢前言
前几篇文章中,笔者介绍了rpc
的原理和目的,也介绍了需要使用的部分第三方库
和我们所需实现的功能
现在我们着手项目实现篇章
,目前零碎接口 、 项目消息字段类型 和 抽象层的封装 都已经完成了
截至上一篇文章,我们已经完成了 rpc框架 的实现
接下来我们将对 服务端 的 registry & discovery 进行实现,让其能够更加便捷
🏳️🌈一、重新理一遍思路
说实话,到这里笔者的脑子已经不清醒了,每个模块在实现的时候都很明白,放在一起就特别的困惑,所以这里再回顾一遍这个 rpc框架 的整个逻辑
1.1 首先,是最基本的三个前置块

1.2 抽象层子类的细分

这部分至关重要,它将整个框架分开来,使得 客户端 与 服务端 能够凭借着 缓冲区、连接、协议 串联起来,真正实现通信,但此时,通信模式仅仅是 一对一。
所以就需要一个 dispatcher 作为中间的转承,使得多对多的模式实现
1.3 dispatcher 分发转承中心
dispatcher 的两个最大的功能
- 找到消息类型对应的业务处理函数,并调用
- 关联消息类型和消息处理方法,并存储
这里提示一下
- rcp 中的服务 service 是指这个框架所能提供的服务,也就是那些回调函数所整合的功能
- 而服务端,是指 各个具有处理各种消息功能的函数(主机) 的集合
1.4 服务端
首先是 rpc_route.hpp
这部分,通过模块化设计,实现了 RPC 服务端核心功能,包括服务注册、参数校验、请求路由和线程安全管理。

然后就是这篇要实现的 rcp_registry.hpp
,这段代码通过分层设计实现了服务注册与发现 的核心功能
最后是一整个 服务端 逻辑,也就是 rcp_server.hpp
通过消息协议和 Dispatcher 实现松耦合交互,构建灵活可扩展的 RPC 框架

1.5 客户端
🏳️🌈二、服务端注册类实现
2.1 核心设计目标
该类用于管理分布式系统中的服务提供者(Provider),核心功能包括:
- 服务注册:新服务提供者上线时注册方法与连接信息。
- 服务发现:根据方法名查询可用的服务提供者地址。
- 生命周期管理:处理服务提供者的上下线,维护提供者-连接映射关系。
- 线程安全:通过互斥锁保护共享数据结构的并发访问。
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 关键方法
- addProvider() - 服务注册
bash
void addProvider(const BaseConnection::ptr& c, const Address& h, const std::string& method)
功能 :当服务提供者注册新方法时调用,将方法与连接关联。
流程:
- 查找或创建 Provider:通过连接 c 在 _conns 中查找现有 Provider,若不存在则创建并绑定连接。
- 更新方法列表:将方法 method 添加到 Provider 的方法列表,并将该 Provider 注入 _providers[method] 的集合。
- 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 核心接口分析
- addDiscoverer() - 订阅服务
bash
Discoverer::ptr addDiscoverer(const BaseConnection::ptr& c, const std::string& method)
功能 :为客户端新增服务订阅,记录方法名并关联连接。
流程:
- 查找或创建 Discoverer:通过连接 c 在 _conns 中查找现有发现者,若不存在则创建并绑定连接。
- 更新订阅列表:将方法 method 添加到发现者的订阅列表,并将该发现者注入 _discoverers[method] 的集合。
- deleteDiscoverer() - 取消订阅
bash
void deleteDiscoverer(const BaseConnection::ptr& c)
功能 :移除客户端连接及其订阅信息。
流程:
- 清理方法关联:遍历发现者的订阅方法,从 _discoverers 的对应集合中删除该发现者。
- 删除连接记录:从 _conns 中移除连接。
优点:锁覆盖完整操作,避免中间状态不一致。
- 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 关键接口分析
- onServiceRequest() - 请求入口
bash
void onServiceRequest(const BaseConnection::ptr& conn, const ServiceRequest::ptr& msg)
功能 :处理客户端服务请求,分为注册与发现两种逻辑分支。
流程:
- 注册分支:调用 _providers->addProvider() 注册服务提供者,并触发 _discoverers->onlineNotify() 通知订阅者。
- 发现分支:调用 _discoverers->addDiscoverer() 记录订阅关系,并返回当前服务地址列表。
- 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实现 做了一个较为详细的介绍,不知道对你有没有帮助呢
觉得博主写得还不错的三连支持下吧!会继续努力的~
