从零开始实现JsonRpc框架(基于c++代码)——10_Rpc客户端服务端封装

客户端

服务注册

在里边我们只做服务注册的封装。只对服务注册响应进行处理回调。

        // 注册服务端, 向注册中新注册自己的方法
        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 &params, 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 &params, 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 &params, 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 &params, 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值