[实现Rpc] 测试 | rpc部分功能联调 | debug | 理解bind

news/2025/2/26 7:01:24

目录

服务端

客户端

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 查看 电脑进程


http://www.niftyadmin.cn/n/5868267.html

相关文章

Node.js 内置模块简介(带示例)

目录 1. fs&#xff08;文件系统&#xff09;模块 2. http 模块 3. path 模块 4. os 模块 5. events 模块 6. crypto 模块 1. fs&#xff08;文件系统&#xff09;模块 fs 模块提供了与文件系统进行交互的功能&#xff0c;包括文件的读写、删除、重命名等操作。它有同步…

安装VM和Centos

安装VM 一、打开虚拟机 二、选择典型 三、选择光盘 四、指定虚拟机位置 五、设置磁盘大小并拆分为多个文件 六、完成 安装Centos 一、上述过程完成后我们直接打开虚拟机 二、语言选择中文 三、默认安装位置并点击完成 四、点击开始安装 五、点击设置密码 设置完密码后点击完成…

Qt基础之四十九:Qt属性系统(Property System)

Qt提供了一个复杂的属性系统,类似于一些编译器供应商提供的属性系统。然而,作为一个独立于编译器和平台的库,Qt不依赖于__property或[property]等非标准编译器功能。Qt解决方案适用于Qt支持的每个平台上的任何标准C++编译器。它基于元对象系统(Meta-Object System),该系统…

1.介绍一下TCP/IP模型和OSI模型的区别【中高频】

OSI模型 将 这个协议 划分为7个不同的层级&#xff0c;分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层&#xff0c;而TCP/IP模型只有4个层级&#xff0c;分别为网络接口层、网络层、传输层和应用层&#xff0c;其中应用层在用户态&#xff0c;传输层及以下…

Java 中 ArrayList 和 LinkedList 的区别及使用场景

文章目录 Java 中 ArrayList 和 LinkedList 的区别及使用场景1. 底层数据结构ArrayListLinkedList 2. 性能对比2.1 访问元素&#xff08;随机访问&#xff09;2.2 插入和删除元素2.3 内存占用 3. 使用场景适合使用 ArrayList 的场景适合使用 LinkedList 的场景 4. 代码示例Arra…

Apache Doris 索引的全面剖析与使用指南

搞大数据开发的都知道&#xff0c;想要在海量数据里快速查数据&#xff0c;就像在星图里找一颗特定的星星&#xff0c;贼费劲。不过别慌&#xff0c;数据库索引就是咱们的 “定位神器”&#xff0c;能让查询效率直接起飞&#xff01;就拿 Apache Doris 这个超火的分析型数据库来…

leetcode刷题记录(一百二十二)——46. 全排列

&#xff08;一&#xff09;问题描述 51. N 皇后 - 力扣&#xff08;LeetCode&#xff09;51. N 皇后 - 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后…

Ubuntu系统创建mariadb数据库(mysql),开通局域网络内连接

Ubuntu系统创建mariadb数据库&#xff08;mysql),开通局域网络内连接 1、安装数据库 如果你确定系统中没有安装 mariadb&#xff0c;可以使用以下命令进行安装&#xff1a; sudo apt update sudo apt install mariadb-server -y如果你只想安装客户端&#xff0c;可以使用以下…