介绍
上一节中,我们介绍了protobuf,简单来说,它是一种消息数据格式,其作用类似于json,但是比json的使用效率要高。
除此以外,我们介绍了protobuf的简单使用,也就是如何可以像使用json一样,将消息数据进行序列化和反序列化
nullhttps://blog.csdn.net/qq_58158950/article/details/136277730?spm=1001.2014.3001.5501但是在日常开发中,除了我们在上节中会使用到的普通数据之外,我们还会用到列表(数组)类型和映射表类型的数据,本节我们将介绍如何使用protobuf对列表类型的数据进行序列化和反序列化
使用
protobuf中的代码复用
仍旧首先编写protobuf配置文件
在上一节中,我们定义登录响应消息类型的时候有两个成员变量errcode和errmasg,这两个成员变量的作用就是来告诉客户端我们发送给服务端的请求是否出错以及出错信息。
message loginResponse
{
int32 errcode=1;
string errmsg=2;
bool success=3;
}
因此作为响应消息,这两个成员变量是必须的,比如我们如果要定义一个注册请求消息
message regResponse
{
int32 errcode=1;
string errmsg=2;
bool success=3;
}
显然,这种定义方式不符合代码的复用,因此,我们完全可以将这两个成员变量单独拿出来定义一个类型
//封装响应消息
message resultCode
{
int32 errcode=1;
bytes errmsg=2;
}
那么登录响应消息就变成了
//登录响应消息
message loginResponse
{
resultCode resMsg=1;
bool success=3;
}
而在c++代码中,我们想要使用loginResponse类的resultCode 成员变量时,就需要这样写
void test()
{
loginResponse reqb;
//获取resultCode成员对象的指针,然后再通过该指针设置成员变量
//该指针的获取方法是mutable_成员变量名称
resultCode*rc= reqb.mutable_resmsg();
rc->set_errcode(1);
rc->set_errmsg("登录处理失效");
}
protobuf中的列表数据类型
接下来我们介绍protobuf中列表数据类型
我们继上述配置文件代码,再定义一个user消息类型,其中性别成员变量是一个枚举类型
//用户消息
message user
{
bytes name=1;
uint32 age=2;
enum sex
{
man=0;
woman=1;
}
}
我们再定义一个好友列表请求和好友列表响应消息
//好友列表请求
message friendListReq
{
int32 userid=1;
}
//好友列表请求响应
message friendListResponse
{
resultCode resMsg=1;
// repeated关键字表示该消息是一个列表,而不是单个消息
repeated user friendList=2;
}
由于好友列表响应返回的消息中,好友不会只有一个,因此需要返回一个user列表(数组),我们使用repeated关键字进行说明
完整的protobuf配置文件如下
syntax="proto3";//声明protobuf版本
package rpcProto;//声明了代码所在的命名空间
//定义登录请求消息类型
message loginRequest
{
bytes name=1;//表示loginRequest消息的第一个字段
bytes passwd=2;//表示loginRequest消息的第二个字段
}
//封装响应消息
message resultCode
{
int32 errcode=1;
bytes errmsg=2;
}
//登录响应消息
message loginResponse
{
resultCode resMsg=1;
bool success=3;
}
//用户消息
message User
{
bytes name=1;
uint32 age=2;
enum Sex
{
man=0;
woman=1;
}
Sex sex=3;
}
//好友列表请求
message friendListReq
{
int32 userid=1;
}
//好友列表请求响应
message friendListResponse
{
resultCode resMsg=1;
// repeated关键字表示该消息是一个列表,而不是单个消息
repeated User friendList=2;
}
在终端输入以下代码生成对应的类文件
protoc test.proto --cpp_out=./
在c++代码中测试
#include<iostream>
#include<string>
#include<test.pb.h>
using namespace std;
using namespace rpcProto;
void test()
{
friendListResponse fres;
resultCode* pc=fres.mutable_resmsg();
pc->set_errcode(0);
pc->set_errmsg("请求无错");
// 使用add_列表变量名获取列表消息指针
User *user1=fres.add_friendlist();
user1->set_name("zhangsan");
user1->set_age(20);
user1->set_sex(User::man);
User *user2=fres.add_friendlist();
user2->set_name("lisi");
user2->set_age(22);
user2->set_sex(User::woman);
cout<<fres.friendlist_size()<<endl;
}
int main()
{
test();
return 0;
}