客户端
服务注册
在里边我们只做服务注册的封装。只对服务注册响应进行处理回调。
// 注册服务端, 向注册中新注册自己的方法
class ProviderClient
{
public:
using ptr = std::shared_ptr<ProviderClient>;
ProviderClient(const std::string &ip, int port)
: _requestor(make_shared<Requestor>()), _provider(make_shared<Provider>(_requestor)), _dispatcher(DispatcherFactory::create())
{
auto rsp_callback = std::bind(&zgwrpc::client::Requestor::OnMessage, _requestor.get(), placeholders::_1, placeholders::_2);
_dispatcher->registerHandler<BaseMessage>(MType::RSP_SERVICE, rsp_callback);
_client = zgwrpc::ClientFactory::create(port, ip);
_client->setMessageCallback(bind(&zgwrpc::Dispatcher::dispatch, _dispatcher, placeholders::_1, placeholders::_2));
_client->connect();
}
// 提供服务注册功能
bool RegistryClient(const std::string &method, const Address &host)
{
return _provider->RegistryMethod(_client->connection(), method, host);
}
private:
client::Requestor::ptr _requestor;
client::Provider::ptr _provider;
Dispatcher::ptr _dispatcher;
BaseClient::ptr _client;
};
发现服务
在服务发现段,不仅会进行服务发现,接收请求到的消息,当rpc服务端上线时还会收到注册中心传来的上线和下线请求。
// 发现服务端-客户端
class DiscoverClient
{
public:
using ptr = std::shared_ptr<DiscoverClient>;
DiscoverClient(const std::string ip, int port, Discover::DeleCallback dele_callback)
: _requestor(make_shared<Requestor>()), _discover(make_shared<Discover>(_requestor, dele_callback)), _dispatcher(DispatcherFactory::create())
{
auto rsp_callback = std::bind(&zgwrpc::client::Requestor::OnMessage, _requestor.get(), placeholders::_1, placeholders::_2);
auto req_callback = std::bind(&Discover::OnServiceRequst, _discover.get(), placeholders::_1, placeholders::_2);
_dispatcher->registerHandler<BaseMessage>(MType::RSP_SERVICE, rsp_callback);
_dispatcher->registerHandler<ServiceRequest>(MType::REQ_SERVICE, req_callback);
_client = zgwrpc::ClientFactory::create(port, ip);
_client->setMessageCallback(bind(&zgwrpc::Dispatcher::dispatch, _dispatcher, placeholders::_1, placeholders::_2));
_client->connect();
}
// 向外提供服务发现接口
bool Discoverclient(const std::string &method, Address &host)
{
return _discover->ServiceDiscovery(_client->connection(), method, host);
}
private:
client::Requestor::ptr _requestor;
client::Discover::ptr _discover;
Dispatcher::ptr _dispatcher;
BaseClient::ptr _client;
};
Rpc客户端
在rpc客户端中我们封装了服务发现客户端,我们可以选择是否启用服务发现功能,但是我们都有了注册中心那一般这个设置是默认开启的
// rpc请求客户端
class RpcClient
{
public:
// disable_discovery:是否禁用服务发现,决定传入的地址信息时服务注册中心,还是服务提供者的地址
RpcClient(bool enable_discovery, const std::string &ip, int port)
: _enable_discovery(enable_discovery), _requestor(std::make_shared<Requestor>()),
_rpc_caller(std::make_shared<RpcCaller>(_requestor)),
_dispatcher(DispatcherFactory::create())
{
auto rsp_callback = std::bind(&zgwrpc::client::Requestor::OnMessage, _requestor.get(), placeholders::_1, placeholders::_2);
_dispatcher->registerHandler<BaseMessage>(MType::RSP_RPC, rsp_callback);
// 如果启用服务发现,则最先创建一个服务发现客户端
if (_enable_discovery)
{
auto dele_callback = std::bind(&RpcClient::DelClient, this, placeholders::_1);
_discover = std::make_shared<DiscoverClient>(ip, port, dele_callback);
}
// 如果不启用服务发现,则直接创建一个服务提供者客户端
else
{
_client = zgwrpc::ClientFactory::create(port, ip);
_client->setMessageCallback(bind(&zgwrpc::Dispatcher::dispatch, _dispatcher, placeholders::_1, placeholders::_2));
_client->connect();
}
}
bool call(const string &method, const Json::Value ¶ms, Json::Value &result)
{
// 如果启用服务发现,则先进行服务发现,获取服务提供者的地址信息
BaseClient::ptr client = GetClient(method);
if (client.get() == nullptr)
return false;
return _rpc_caller->call(client->connection(), method, params, result);
}
// 异步调用
bool call(const string &method, const Json::Value ¶ms, std::future<Json::Value> &result)
{
BaseClient::ptr client = GetClient(method);
if (client.get() == nullptr)
return false;
return _rpc_caller->call(client->connection(), method, params, result);
}
// 异步回调
bool call(const string &method, const Json::Value ¶ms, const RpcCaller::JsonCallbackResponse &callback)
{
BaseClient::ptr client = GetClient(method);
if (client.get() == nullptr)
return false;
return _rpc_caller->call(client->connection(), method, params, callback);
}
private:
BaseClient::ptr NewClient(const Address &host)
{
auto client = zgwrpc::ClientFactory::create(host.second, host.first);
client->setMessageCallback(bind(&zgwrpc::Dispatcher::dispatch, _dispatcher, placeholders::_1, placeholders::_2));
client->connect();
AddClient(host, client);
return client;
}
BaseClient::ptr GetClient(const Address &host)
{
std::unique_lock<std::mutex> lock(_mutex);
auto it = _clients.find(host);
if (it != _clients.end())
{
return it->second;
}
return nullptr;
}
BaseClient::ptr GetClient(const std::string &method)
{
BaseClient::ptr client;
if (_enable_discovery)
{
// 通过服务发现,获取服务提供者的地址信息
// 查看服务提供者是否实例化客户端,有则使用,没有则创建
Address host;
bool ret = _discover->Discoverclient(method, host);
if (ret == false)
{
LOG(LogLevel::ERROR) << "没有发现到服务提供者";
return nullptr;
}
else
{
client = GetClient(host);
if (client == nullptr)
{
client = NewClient(host);
}
}
}
else
{
client = _client;
}
return client;
}
void AddClient(const Address &host, BaseClient::ptr client)
{
std::unique_lock<std::mutex> lock(_mutex);
_clients.insert(std::make_pair(host, client));
}
void DelClient(const Address &host)
{
std::unique_lock<std::mutex> lock(_mutex);
_clients.erase(host);
}
struct AdressHash
{
size_t operator()(const Address &addr) const
{
std::string host = addr.first + std::to_string(addr.second);
return std::hash<std::string>{}(host);
}
};
// 内部多了一个服务发现,rpc请求时只能向请求到的主机进行rpc调用
client::Requestor::ptr _requestor;
client::DiscoverClient::ptr _discover;
client::RpcCaller::ptr _rpc_caller;
Dispatcher::ptr _dispatcher;
BaseClient::ptr _client;
bool _enable_discovery;
std::mutex _mutex;
std::unordered_map<Address, BaseClient::ptr, AdressHash> _clients; // 根据主机地址,创建的连接池,获取到的客户端地址会最先在此处进行缓存
};
服务端
服务注册中心
服务中心服务端封装,作为服务端要处理的就是服务中兴请求
//服务注册中心服务端
class Rpc_Registry
{
public:
Rpc_Registry(int port):_pd_manager(make_shared<PDManger>()),_dispatcher(make_shared<Dispatcher>())
,_router(make_shared<Rpc_Router>())
{
auto message_callback=std::bind(&PDManger::OnServiceRequest,_pd_manager,std::placeholders::_1,std::placeholders::_2);
_dispatcher->registerHandler<ServiceRequest>(MType::REQ_SERVICE,message_callback);
_server=ServerFactory::create(port);
_server->setMessageCallback(std::bind(&Dispatcher::dispatch, _dispatcher, std::placeholders::_1, std::placeholders::_2));
_server->setCloseCallback(std::bind(&Rpc_Registry::OnConnShutdown, this, std::placeholders::_1));
}
void OnConnShutdown(const BaseConnection::ptr &conn)
{
_pd_manager->OnServiceShutdown(conn);
}
void start()
{
_server->start();
}
private:
BaseServer::ptr _server;
Rpc_Router::ptr _router;
PDManger::ptr _pd_manager;
Dispatcher::ptr _dispatcher;
};
Rpc服务端
在Rpc服务端中,需要添加一个服务发现的客户端,同样采用是否启用的选项,一般默认打开
class Rpc_Server
{
public:
//
Rpc_Server(const Address &acess, const Address& provider, bool enable_register=false):
_acess(acess),_dispatcher(DispatcherFactory::create()),_router(make_shared<Rpc_Router>()),_enable_register(enable_register)
{
//检查是否启用register
if(enable_register)
{
_provider_client=std::make_shared<client::ProviderClient>(provider.first,provider.second);
}
auto message_callback=std::bind(&Rpc_Router::OnRpcRequest,_router,std::placeholders::_1,std::placeholders::_2);
_dispatcher->registerHandler<RpcRequest>(MType::REQ_RPC,message_callback);
_server=ServerFactory::create(acess.second);
_server->setMessageCallback(std::bind(&Dispatcher::dispatch, _dispatcher, std::placeholders::_1, std::placeholders::_2));
}
void Register(const ServerDescribe::ptr &server)
{
if(_enable_register)
{
bool ret=_provider_client->RegistryClient(server->MethodName(),_acess);
if(ret==false)
LOG(LogLevel::ERROR)<<"注册服务失败";
}
_router->Register(server);
}
void start()
{
_server->start();
}
private:
bool _enable_register;
Address _acess;
client::ProviderClient::ptr _provider_client;
Dispatcher::ptr _dispatcher;
Rpc_Router::ptr _router;
BaseServer::ptr _server;
};
测试代码
client
#include"../Client/Rpc_client.hpp"
void Callback(const Json::Value& result)
{
cout<<"result:"<<result["result"].asInt()<<endl;
}
void test7()
{
Json::Value params,result;
params["num1"] = 201;
params["num2"] = 221;
zgwrpc::client::RpcClient client(true, "127.0.0.1", 8080);
cout<<"call Add"<<endl;
bool ret = client.call("Add", params, result);
if(ret==false)
{
cout<<"call failed"<<endl;
}
else
{
cout<<result["result"].asInt()<<endl;
}
Json::Value params1;
params1["num1"] = 999;
params1["num2"] = 111;
ret=client.call("Add",params1,Callback);
std::string str="第五人格";
Json::Value paramsgame;
std::future<Json::Value> gameresult;
paramsgame["game"]=str;
client.call("Game",paramsgame,gameresult);
cout<<"result:"<<gameresult.get()<<endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
}
int main()
{
test7();
return 0;
}
server
#include"../Server/Rpc_server.hpp"
bool Add(const Json::Value &req, Json::Value &rsp)
{
int num1 = req["num1"].asInt();
int num2 = req["num2"].asInt();
rsp["result"]=num1+num2;
return true;
}
bool Gamer(const Json::Value ¶ms, Json::Value &result)
{
string game=params["game"].asString();
if(game=="原神")
result["正在打开"]="原神启动";
else if(game=="魔兽世界")
result["正在打开"]="魔兽世界启动";
else if( game=="第五人格")
result["正在打开"]="第五人格启动";
else result["正在打开"]="游戏不存在";
return true;
}
int main()
{
zgwrpc::Dispatcher::ptr dispatcher=zgwrpc::DispatcherFactory::create();
auto router=make_shared<zgwrpc::server::Rpc_Router>();
auto cb=std::bind(&zgwrpc::server::Rpc_Router::OnRpcRequest,router.get(),placeholders::_1,placeholders::_2);
zgwrpc::server::ServerDescribeBuilder buiderAdd;
buiderAdd.SetCallback(Add);
buiderAdd.SetMthodName("Add");
buiderAdd.SetReturnType(zgwrpc::server::VType::INTEGRAL);
buiderAdd.SetParamsDescribe("num1", zgwrpc::server::VType::INTEGRAL);
buiderAdd.SetParamsDescribe("num2", zgwrpc::server::VType::INTEGRAL);
zgwrpc::server::ServerDescribeBuilder buiderGame;
buiderGame.SetCallback(Gamer);
buiderGame.SetMthodName("Game");
buiderGame.SetReturnType(zgwrpc::server::VType::STRING);
buiderGame.SetParamsDescribe("game", zgwrpc::server::VType::STRING);
shared_ptr<zgwrpc::server::ServerDescribeBuilder> rpcserver_builder=make_shared<zgwrpc::server::ServerDescribeBuilder>();
rpcserver_builder->SetMthodName("Add");
rpcserver_builder->SetParamsDescribe("num1",zgwrpc::server::VType::INTEGRAL);
rpcserver_builder->SetParamsDescribe("num2",zgwrpc::server::VType::INTEGRAL);
rpcserver_builder->SetReturnType(zgwrpc::server::VType::INTEGRAL);
rpcserver_builder->SetCallback(Add);
zgwrpc::Address a1=make_pair("127.0.0.1",9090);
zgwrpc::Address a2=make_pair("127.0.0.1",8080);
zgwrpc::server::Rpc_Server server(a1,a2,true);
server.Register(rpcserver_builder->Build());
server.Register(buiderAdd.Build());
server.Register(buiderGame.Build());
cout<<"server start"<<endl;
server.start();
return 0;
}
regesrtry
#include"../Common/Detail.hpp"
#include"../Server/Rpc_server.hpp"
int main()
{
zgwrpc::server::Rpc_Registry registry(8080);
registry.start();
return 0;
}