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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/977950.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode每日精进:622.设计循环队列

题目链接&#xff1a;622.设计循环队列 题目描述&#xff1a; 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个…

网络安全学习-常见安全漏洞检测以及修复方法-1

渗*透测试 渗透测试就是模拟攻击者入侵系统&#xff0c;对系统进行一步步渗透&#xff0c;发现系统的脆弱环节和隐藏风险。形成测试报告提供给系统的所有者&#xff0c;所有者根据报告对系统进行加固&#xff0c;提升系统的安全性&#xff0c;防止真正的攻击者入侵。 渗透测试…

鸿蒙开发深入浅出01(基本环境搭建、页面模板与TabBar)

鸿蒙开发深入浅出01&#xff08;基本环境搭建、页面模板与TabBar&#xff09; 1、效果展示2、下载 DevEco Studio3、创建项目4、新建页面模板5、更改应用信息6、新建以下页面7、Index.ets8、真机运行9、图片资源文件 1、效果展示 2、下载 DevEco Studio 访问官网根据自己的版本…

C/C++ | 每日一练 (4)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 C/C | 每日一练 (4)题目参考答案基础容器序列容器std:…

(八)趣学设计模式 之 装饰器模式!

目录 一、 啥是装饰器模式&#xff1f;二、 为什么要用装饰器模式&#xff1f;三、 装饰器模式的实现方式四、 装饰器模式的优缺点五、 装饰器模式的应用场景六、 装饰器模式 vs 代理模式七、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢…

快节奏生活

在当今快节奏的商务环境中&#xff0c;效率成为了决定企业竞争力的关键因素之一。亿可达软件连接平台&#xff0c;以其独特的功能和优势&#xff0c;为职场人士带来了前所未有的便捷与高效&#xff0c;成为了众多用户心中的“宝藏”工具。 1、亿可达&#xff1a;自动化流程的搭…

Jenkins protoc: command not found

个人博客地址&#xff1a;Jenkins protoc: command not found | 一张假钞的真实世界 在使用Jenkins编译Hadoop3.1.2时报错信息如下&#xff1a; [INFO] --- hadoop-maven-plugins:3.1.2:protoc (compile-protoc) hadoop-common --- [WARNING] [protoc, --version] failed: j…

SOME/IP协议的建链过程

在SOME/IP协议中,建立服务通信链路的过程主要涉及服务发现机制,通常需要以下三次交互: 服务提供者广播服务可用性(Offer Service) 服务提供者启动后,周期性地通过Offer Service消息向网络广播其提供的服务实例信息(如Service ID、Instance ID、通信协议和端口等)。 作用…

考研/保研复试英语问答题库(华工建院)

华南理工大学建筑学院保研/考研 英语复试题库&#xff0c;由华工保研er和学硕笔试第一同学一起整理&#xff0c;覆盖面广&#xff0c;助力考研/保研上岸&#xff01;需要&#x1f447;载可到文章末尾见小&#x1f360;。 以下是主要内容&#xff1a; Part0 复试英语的方法论 Pa…

Linux7-线程

一、前情回顾 chdir();功能&#xff1a; 函数用于改变当前进程的工作目录。 参数&#xff1a;路径&#xff08;Path&#xff09;&#xff1a;这是一个字符串参数&#xff0c;表示要切换到的目标目录的路径。 返回值&#xff1a; 成功&#xff1a;在成功改变当前工作目…

防火墙双机热备---VRRP,VGMP,HRP(超详细)

双机热备技术-----VRRP&#xff0c;VGMP&#xff0c;HRP三个组成 注&#xff1a;与路由器VRRP有所不同&#xff0c;路由器是通过控制开销值控制数据包流通方向 防火墙双机热备&#xff1a; 1.主备备份模式 双机热备最大的特点就是防火墙提供了一条专门的备份通道&#xff08;心…

LabVIEW形状误差测量系统

在机械制造领域&#xff0c;形状与位置公差&#xff08;GD&T&#xff09;直接影响装配精度与产品寿命。国内中小型机加工企业因形状误差导致的返工率高达12%-18%。传统测量方式存在以下三大痛点&#xff1a; ​ 设备局限&#xff1a;机械式千分表需人工读数&#xff0c;精度…

本地部署大模型: LM Studio、Open WebUI 与 Chatbox 全面对比以及选型指南

1. 工具概述 LM Studio 定位&#xff1a;专注于本地化大模型实验与推理的桌面工具&#xff0c;支持多模型并行、Hugging Face集成及离线运行。 核心功能&#xff1a; 图形化界面直接加载GGUF模型文件&#xff0c;支持NVIDIA/AMD GPU加速。 内置OpenAI兼容API&#xff0c;可搭…

百度觉醒,李彦宏渴望光荣

文 | 大力财经 作者 | 魏力 2025年刚刚开年&#xff0c;被一家名为DeepSeek的初创公司强势改写。在量化交易出身的创始人梁文锋的带领下&#xff0c;这支团队以不到ChatGPT 6%的训练成本&#xff0c;成功推出了性能可与OpenAI媲美的开源大模型。 此成果一经问世&#xff0c;…

mysql 迁移到人大金仓数据库

我是在windows上安装了客户端工具 运行数据库迁移工具 打开 在浏览器输入http://localhost:54523/ 账号密码都是kingbase 添加mysql源数据库连接 添加人大金仓目标数据库 添加好的两个数据库连接 新建迁移任务 选择数据库 全选 迁移中 如果整体迁移不过去可以单个单个或者几个…

Spring Cloud — Hystrix 服务隔离、请求缓存及合并

Hystrix 的核心是提供服务容错保护&#xff0c;防止任何单一依赖耗尽整个容器的全部用户线程。使用舱壁隔离模式&#xff0c;对资源或失败单元进行隔离&#xff0c;避免一个服务的失效导致整个系统垮掉&#xff08;雪崩效应&#xff09;。 1 Hystrix监控 Hystrix 提供了对服务…

【链 表】

【链表】 一级目录1. 基本概念2. 算法分析2.1 时间复杂度2.2 空间复杂度2.3 时空复杂度互换 线性表的概念线性表的举例顺序表的基本概念顺序表的基本操作1. 初始化2. 插入操作3. 删除操作4. 查找操作5. 遍历操作 顺序表的优缺点总结优点缺点 树形结构图形结构单链表基本概念链表…

记录锁,间隙锁,Next-Key Lock

记录锁&#xff0c;间隙锁&#xff0c;Next-Key Lock mysql的锁机制一、InnoDB行锁的种类1、记录锁&#xff08;Record Lock&#xff09;&#xff08;1&#xff09;不加索引&#xff0c;两个事务修改同一行记录&#xff08;2&#xff09;不加索引&#xff0c;两个事务修改同一表…

vue3父子组件props传值,defineprops怎么用?(组合式)

目录 1.基础用法 2.使用解构赋值的方式定义props 3.使用toRefs的方式解构props (1).通过ref响应式变量&#xff0c;修改对象本身不会触发响应式 1.基础用法 父组件通过在子组件上绑定子组件中定义的props&#xff08;:props“”&#xff09;传递数据给子组件 <!-- 父组件…

鸿蒙Next-方法装饰器以及防抖方法注解实现

以下是关于 鸿蒙Next&#xff08;HarmonyOS NEXT&#xff09;中 MethodDecorator 的详细介绍及使用指南&#xff0c;结合了多个技术来源的实践总结&#xff1a; 一、MethodDecorator 的概念与作用 MethodDecorator 是鸿蒙Next框架中用于装饰类方法的装饰器&#xff0c;属于 Ark…