代码编织梦想

例子1

test.proto文件如下:

syntax = "proto3"; // 声明了protobuf版本

package fixbug; // 声明了代码所在的包(生成C++代码后就是namespace 名字)

// 定义登录消息类型
message LoginRequest
{
    string name = 1; // =1 代表name是这个message第一个字段,不是指name的值
    string pwd = 2;
}

// 定义登录响应消息
message LoginResponse
{
    int32 errcode = 1;
    string errmsg = 2;
    bool success = 3;
}

对proto文件进行编译:

protoc test.proto --cpp_out=./

产生两个cpp文件

在这里插入图片描述

测试代码main.cc如下:

#include "test.pb.h"
#include <iostream>
#include <string>
using namespace fixbug; // 工作中不要这样!!防止命名空间污染

int main()
{
    // 封装login请求对象的数据
    LoginRequest req;
    req.set_name("lisi");
    req.set_pwd("123456");

    std::string send_str;
    // 将成员值序列化为字符串
    if(req.SerializeToString(&send_str))
    {
        std::cout << send_str.c_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;
}
jyhlinux@ubuntu:~/share/mprpc/test/protobuf$ g++ main.cc test.pb.cc -o main -lprotobuf -L/usr/local/lib
jyhlinux@ubuntu:~/share/mprpc/test/protobuf$ ./main

实验结果

lisi123456

lisi

123456

注意

建议将string类型替换为bytes类型,因为bytes直接存二进制文件,效率更高一点,如果用string,最后还要将其转换为字节数据,而bytes则不需要。最后结果和上面相同

syntax = "proto3"; // 声明了protobuf版本

package fixbug; // 声明了代码所在的包(生成C++代码后就是namespace 名字)

// 定义登录消息类型
message LoginRequest
{
    bytes name = 1; // =1 代表name是这个message第一个字段,不是指name的值
    bytes pwd = 2;
}

// 定义登录响应消息
message LoginResponse
{
    int32 errcode = 1;
    bytes errmsg = 2;
    bool success = 3;
}

例子2——列表

protobuf文件test.proto

列表需要在遍变量声明前加repeated

syntax = "proto3"; // 声明了protobuf版本

package fixbug; // 声明了代码所在的包(生成C++代码后就是namespace 名字)

message ResultCode
{
    int32 errcode = 1;
    bytes errmsg = 2;
}

// 定义登录消息类型
message LoginRequest
{
    bytes name = 1; // =1 代表name是这个message第一个字段,不是指name的值
    bytes pwd = 2;
}

// 定义登录响应消息
message LoginResponse
{
    ResultCode result = 1;
    bool success = 3;
}

message GetFriendListRequest
{
    uint32 userid = 1;
}

message User
{
    bytes name =1;
    uint32 age = 2;
    enum Sex
    {
        MAN = 0;
        WOMAN = 1;
    }
    Sex sex = 3;
}

message GetFriendListResponse
{
    ResultCode result = 1;
    repeated User friend_list = 2; // repeated表示列表类型!!!
}

测试源代码 main.cc

#include "test.pb.h"
#include <iostream>
#include <string>
using namespace fixbug; // 工作中不要这样!!防止命名空间污染

int main()
{
    // LoginResponse rsp;
    // // 对象成员的修改方法,要先获取成员的指针
    // ResultCode *rc = rsp.mutable_result();
    // rc->set_errcode(1);
    // rc->set_errmsg("登录失败");

    GetFriendListResponse rsp;
    ResultCode *rc = rsp.mutable_result();
    rc->set_errcode(0);
   
    User *user1 = rsp.add_friend_list(); // 返回一个指向User类型指针,我们往里填数据就是在新的位置加入元素了
    user1->set_name("zhangsan");
    user1->set_age(20);
    user1->set_sex(User::MAN);

    User *user2 = rsp.add_friend_list(); // 返回一个指向User类型指针,我们往里填数据就是在新的位置加入元素了
    user2->set_name("lisi");
    user2->set_age(21);
    user2->set_sex(User::MAN);

    //std::cout << rsp.friend_list_size() << std::endl;

    // 打印列表元素
    int n = rsp.friend_list_size();
    for(int i = 0; i < n; ++i)
    {
        std::cout << rsp.friend_list(i).name() << " "<< rsp.friend_list(i).age() << " " << rsp.friend_list(i).sex() << std::endl;
    }
    return 0;
}

编译执行

jyhlinux@ubuntu:~/share/mprpc/test/protobuf$ protoc test.proto  --cpp_out=./
jyhlinux@ubuntu:~/share/mprpc/test/protobuf$ g++ main.cc test.pb.cc -o main -lprotobuf -L/usr/local/lib
jyhlinux@ubuntu:~/share/mprpc/test/protobuf$ ./main 

执行结果

zhangsan 20 0

lisi 21 0

例子3——定义方法类型(用于描述rpc方法)的成员

下面的例子使用service 关键字定义描述rpc方法的类型,并且注意开头要设置option

syntax = "proto3"; // 声明了protobuf版本

package fixbug; // 声明了代码所在的包(生成C++代码后就是namespace 名字)

// 定义下面的选项,表示生成service服务类和rpc方法描述,默认不生成
option cc_generic_services = true;

message ResultCode
{
    int32 errcode = 1;
    bytes errmsg = 2;
}

// 定义登录消息类型
message LoginRequest
{
    bytes name = 1; // =1 代表name是这个message第一个字段,不是指name的值
    bytes pwd = 2;
}

// 定义登录响应消息
message LoginResponse
{
    ResultCode result = 1;
    bool success = 3;
}

message GetFriendListRequest
{
    uint32 userid = 1;
}

message User
{
    bytes name =1;
    uint32 age = 2;
    enum Sex
    {
        MAN = 0;
        WOMAN = 1;
    }
    Sex sex = 3;
}

message GetFriendListResponse
{
    ResultCode result = 1;
    repeated User friend_list = 2; // repeated表示列表类型
}

// 在protobuf里定义描述rpc方法的类型
service UserServiceRpc
{
    rpc Login(LoginRequest) returns(LoginResponse);
    rpc GetFriendList(GetFriendListRequest) returns(GetFriendListResponse);
}

通过protoc会生成的UserServiceRpc类(服务提供方使用)和 UserServiceRpc_Stub类(服务调用方使用)

在这里插入图片描述

这也是ServiceProvider,即rpc服务提供者。

UserServiceRpc_Stub类是服务消费者即serviceConsumer

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42120843/article/details/130916412