当前位置: 首页 > news >正文

rpc中常用的数据格式:Protobuf 图文详解

概述

protobuf也叫protocol buffer,是google 的一种数据交换的格式,它跨语言、跨平台。可以实现多种语言文件的数据传输实现(java、c#、c++、go 和 python 等),如一个cpp程序和一个python程序的数据传输。

由于它是一种二进制的格式,比使用 xml 、json进行数据交换快许多。所以它的效率和兼容性都很优秀,可以把它用于分布式应用之间的数据通信。

编译与安装

通过百度网盘分享的文件:proto
链接:https://pan.baidu.com/s/1o7Vmcyofz6r_phLdh-A2lA?pwd=t172 
提取码:t172

解压后运行shell脚本即可

编写简单的proto文件

proto文件

// 声明protobuf的版本
syntax = "proto3";
// 声明代码所在的包, 相当他cpp的namespace
package fixbug;// 定义下面选项, 才可以生成service服务类和rpc方法描述, 默认不生成
option cc_generic_services = true;message ResultCode {int32 errcode = 1;bytes errmsg = 2;bool success = 3;
}// 定义登录消息类型(结构体)
message LoginRequest {// 1 表示数据的序号bytes name = 1; // bytes = stringbytes pwd = 2;
}// 定义登录响应消息类型
message LoginResponse {ResultCode result = 1;bool success = 2;
}message GetFriendListsRequest { uint32 userid = 1; }message User {bytes name = 1;uint32 age = 2;enum Sex {MAN = 0;WOMAN = 1;}Sex sex = 3;
}message GetFriendListsResponse {ResultCode result = 1;bool success = 2;// 存储列表repeated User friend_list = 3;
}// 在protobuf里面定义描述rpc方法的类型 -service
service UserServiceRpc {rpc Login(LoginRequest) returns (LoginResponse);rpc GetFriendList(GetFriendListsRequest) returns (GetFriendListsResponse);
}

在终端中执行

protoc test.proto --cpp_out=./

test.proto是你自定义的proto文件

然后会得到test.pb.h、test.pb.cc文件

proto自定义数据结构与.pb.h中函数的关系

test.pb.h初看有些复杂,但其实都是有规律的

image-20241012201312528

1.常规变量类型

这里的常规变量,指的是string、int等类型,而不是自定义的数据结构

// 定义登录消息类型(结构体)
message LoginRequest {// 1 表示数据的序号bytes name = 1; // bytes = stringbytes pwd = 2;
}

转为pb.cc文件后,主要分为两种读写函数:

  • set_变量名():如set_name(),往name变量中写数据
  • 变量名():如name(),只读访问name变量

2.自定义变量类型

message GetFriendListsResponse {ResultCode result = 1;bool success = 2;// 存储列表repeated User friend_list = 3;
}

转为 pb.cc 文件后,主要分为两种读写函数:

  • mutable_变量名():如ResultCode* mutable_result(),获得变量result的指针,之后就可读可写了
  • 变量名():如name(),只读访问name变量

注意对于 repeated User friend_list 变量,还会有:

使用 repeated 关键字定义的字段在 Protobuf 序列化和反序列化时会被当作一个集合或数组来处理。这个 User friend_list 可以作为一个动态数组来使用。

  • add_变量名():如 User* add_friend_list(),它返回的是要新增元素地址

3.service服务

在proto中我们会定义远程调用的服务函数

service UserServiceRpc {rpc Login(LoginRequest) returns (LoginResponse);rpc GetFriendList(GetFriendListsRequest) returns (GetFriendListsResponse);
}
  • 转为pb.cc文件后,会从 ”结构体“名 (这里是 UserServiceRpc)继承,得到 ”结构体“名_Stub 这个类(这里是UserServiceRpc_Stub
  • UserServiceRpc_Stub 的构造函数是由一个 RpcChannel* channel 作为参数的传入的
  • 而 proto 文件中定义的 LoginGetFriendList 函数,本质上是调用 CallMethod 函数(channel_->CallMethod(descriptor()->method(0),controller, request, response, done);
  • 再追溯一下,RpcChannel 是一个类,里面是 CallMethod 函数是虚函数,这说明 RpcChannel 类以及它的 CallMethod 函数,都需要我们开发者进行重写

序列化与反序列化

  • 序列化是将数据结构或对象转换为可以存储或传输的格式(通常是字节序列/string类型)的过程。

    其目的是将复杂的数据结构转化为一种便于存储、传输或在不同系统之间交换的形式。

  • 反序列化则是序列化的逆过程,它将序列化后的数据(如字节流)重新转换回原始的数据结构或对象。

    假设我们有一个包含学生姓名、年龄和成绩的对象。序列化可能会将这个对象转换为一个特定格式的字符串,如 {“name”:“张三”,“age”:20,“score”:90} 。而反序列化就是把接收到的这样的字符串重新转换回包含姓名、年龄和成绩的学生对象。

image-20241012204439211

【protobuf】ProtoBuf——序列化概念、序列化和反序列化、为什么需要序列化和反序列化、如何实现序列化、ProtoBuf 是什么、ProtoBuf 的使用特点-CSDN博客

#include "test.pb.h"
#include <iostream>
#include <string>
using namespace fixbug;int main()
{// 初始化变量, 封装了login请求对象的数据LoginRequest req;req.set_name("zhang san");req.set_pwd("123456");// 对象数据序列化, => stringstd::string send_str;if(req.SerializeToString(&send_str)){std::cout << send_str << std::endl;}// 从send_str中反序列化一个login请求对象LoginRequest reqB;if(reqB.ParseFromString(send_str)){std::cout << reqB.name() << std::endl;std::cout << reqB.pwd() << std::endl;}return 0;
}

http://www.mrgr.cn/news/49150.html

相关文章:

  • 股票做T如何选择买卖点,股票做T时,怎样综合判断买卖点?
  • 连接数据库和基本信息查询的详细理解和实际操作
  • 从0到1,一篇文章彻底讲透AI的Token到底是什么?如何实际应用
  • 深入理解 Transformer:构建先进 NLP 模型的关键技术
  • 物联网5G模块WIFI模块调式记录(Pico)
  • 【JAVA-数据结构】二叉树
  • 一个月学会Java 第13天 抽象类与接口
  • 如何将docker容器中的软件安装到singularity容器中?
  • 联合查询(详细篇)
  • MediaRecorder + Camera2循环录制视频
  • 企业架构之从理论指南到实践指导企业数字化转型
  • 将图片添加到 PDF 的 5 种方法
  • 架构设计笔记-8-系统质量属性与架构评估
  • SSH隧道验证的原理及实现例子
  • E40.【C语言】练习:有关栈帧的讨论(反汇编分析)
  • 基于Raspberry Pi人脸识别自动门
  • C++中单例推荐写法
  • 【尚硅谷】FreeRTOS学笔记(更新中更新时间2024.10.12)
  • 81.【C语言】数据结构之空间复杂度
  • 探索Spring Cloud Config:构建高可用的配置中心