[实现Rpc] 测试 | rpc部分功能联调 | debug | 理解bind
目录
服务端
客户端
Debug
运行
总结
服务端
调用 on Request 对请求做出回应
on 对...做处理
#include "../../common/net.hpp"
#include "../../common/message.hpp"
#include "../../common/dispatcher.hpp"
#include "../../server/rpc_router.hpp"
#include <thread>
//封装 各类 接口
//细化 实现 各部分功能
//实现 调用
void Add(const Json::Value &req,Json::Value &rsp)
{
int num1=req["num1"].asInt();
int num2=req["num2"].asInt();
rsp=num1+num2;
}
int main()
{
auto dispatcher=std::make_shared<Dispatcher>();
//新增测试
auto router=std::make_shared<bitrpc::server::RpcRouter> ();
//调用 描述接口
std::unique_ptr<bitrpc::server::SDescribeFactory> desc_factory(new bitrpc::server::SDescribeFactory());
//这是 一个工厂对象
desc_factory->setMethodName("Add");
//对 封装的 类型 进行传入
desc_factory->setParamsDesc("num1",bitrpc::server::VType::INTEGRAL);
desc_factory->setParamsDesc("num2",bitrpc::server::VType::INTEGRAL);
desc_factory->setReturnType(bitrpc::server::VType::INTEGRAL);
//回调函数
desc_factory->setCallback(Add);
//调用接口 注册 方法工厂
router->registerMethod(desc_factory->build());
auto cb=std::bind(&bitrpc::server::RpcRouter::onRpcRequest,router.get(),
std::placeholders::_1,std::placeholders::_2);//返回结果 参数检查
dispatcher->registerHandler<bitrpc::RpcRequest>(bitrpc::MType::REQ_RPC,cb);
//在 dispatcher前 ,嵌套一层 router 检查
auto server=ServerFactory::create(8080);
auto message_cb=std::bind(&Dispatcher::onMessage,dispatcher.get(),std::placeholders::_1,std::placeholders::_2);
server->setMessageCallback(message_cb);
server->start();
return 0;
}
客户端
#include "../../common/net.hpp"
#include "../../common/message.hpp"
#include "../../common/dispatcher.hpp"
#include "../../client/requestor.hpp"//进行uuid编号 send
#include "../../client/rpc_caller.hpp"//实现 三种 call方式
#include <thread>
#include <unistd.h>
void onRpcRespond(const BaseConnection::ptr &conn,RpcResponse::ptr &msg)
{
std::cout<<"收到RPC响应";
std::string body=msg->serialize();//序列化
std::cout<<body<<std::endl;
}
void onTopicRespond(const BaseConnection::ptr &conn,TopicResponse::ptr &msg)
{
std::cout<<"收到Topic响应";
std::string body=msg->serialize();
std::cout<<body<<std::endl;
}
int main()
{
//1.0
// auto dispatcher=std::make_shared<Dispatcher>();
// dispatcher->registerHandler<RpcResponse>(MType::RSP_RPC,onRpcRespond);
// dispatcher->registerHandler<TopicResponse>(MType::REQ_TOPIC,onTopicRespond);
//2.0
auto requestor=std::make_shared<bitrpc::client::Requestor>();
auto caller=std::make_shared<bitrpc::client::RpcCaller>(requestor);
auto dispatcher=std::make_shared<Dispatcher>();
auto rsp_cb=std::bind(&bitrpc::client::Requestor::onResponse,requestor.get(),
std::placeholders::_1,std::placeholders::_2);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//客户端 实现uuid和回复 对应
dispatcher->registerHandler<bitrpc::BaseMessage>(MType::RSP_RPC,rsp_cb);
auto client=ClientFactory::create("127.0.0.1",8080);
auto message_cb=std::bind(&Dispatcher::onMessage,dispatcher.get(),std::placeholders::_1,std::placeholders::_2);
client->setMessageCallback(message_cb);
client->connect();
//2.0
auto conn=client->connection();
Json::Value params,result;
//server num1 num2 要对应
params["num1"]=11;
params["num2"]=22;
bool ret=caller->call(conn,"Add",params,result);
if(ret!=false)
{
std::cout<<"result:"<<result.asInt()<<std::endl;
//打印结果
}
auto rpc_req=MessageFactory::create<RpcRequest>();
rpc_req->setMethod("Add");
rpc_req->SetMType(MType::REQ_RPC);
rpc_req->SetId("1111111");
Json::Value param;
param["num1"]=11;
param["num2"]=22;
rpc_req->setParams(param);
//调用 接口
client->send(rpc_req);
sleep(5);
client->shutdown();
return 0;
}
Debug
1.问题
查看:
查看 onresponse
返回的是 BaseMessage,不是上面 主观 想的 rpcresponse 这个子类
- 要用通用的 消息类型,因为之后 requestor 还有可能 去处理 topic 和 server,不能写死了
修改:
sum:使用 类模板 的时候,一定要搞清楚,接收到 到底是 什么类型的东西
2.
关于 日志打印 报错修正
// 在 rpc_caller.hpp 中的相关位置修改如下:
ELOG("rpc请求出错:%s", errReason(rpc_rsp_msg->rcode()).c_str());
// 同样地,在其他地方也需要做类似的修改:
ELOG("rpc回调请求出错:%s", errReason(rpc_rsp_msg->rcode()).c_str());
ELOG("rpc异步请求出错:%s", errReason(rpc_rsp_msg->rcode()).c_str());
3.SDescribe 部分
4.
运行
客户端
服务端
总结
客户端---request-->服务端--respond-->客户端
前文回顾:[C++11#47] (四) function包装器 | bind 函数包装器 | 结合使用
function
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> _st;
map<string,function<int(int,int)>> opFuncMap =
{
{"+",[](int x,int y)->int{return x+y;}},
{"-",[](int x,int y)->int{return x-y;}},
{"*",[](int x,int y)->int{return x*y;}},
{"/",[](int x,int y)->int{return x/y;}},
//这里还可以添加%其他东西,还是很好用的
};
for(auto& str : tokens)
{
if(opFuncMap.count(str) == 0)
{
_st.push(stoi(str));
}
}
bind
double PPlus(int a, double rate, int b)
{
return rate*(a + b);
}
int main()
{
//PPlus
function<double(int, int)> PPlus1 = bind(PPlus, placeholders::_1, 4.0, placeholders::_2);
function<double(int, int)> PPlus2 = bind(PPlus, placeholders::_1, 4.2, placeholders::_2);
cout << PPlus1(5, 3) << endl;
cout << PPlus2(5, 3) << endl;
}
- 重申:_1代表 需要传输的 第一个参数,_2代表要传的第二个参数(rate 是常量)
function 是想对各种可调用对象函数指针、函数对象,lambda进行适配包装给一个统一的类型。
bind 是对可调用的对象的参数进行包装绑定,然后调整,绑死。
win+shift+esc 查看 电脑进程