TheLudGamer 发表于 2021-11-23 06:37

protobuf文件使用详解

通信方式


[*]一个请求对象对应一个返回对象
rpc Login(LoginRequest) returns (LoginResponse) {}
[*]一个请求对象,服务器返回多个结果
rpc Login(LoginRequest) returns (stream LoginResponse) {}3.多个请求对象,一个返回结果
rpc Login(stream LoginRequest) returns (LoginResponse) {}4.多个请求对象,服务器返回多个结果
rpc Login(stream LoginRequest) returns (stream LoginResponse) {}关键字 stream 表示多个值
Protobuf定义


[*]syntax="proto3";
文件的第一行指定了你使用的是proto3的语法:如果你不指定,protocol buffer 编译器就会认为你使用的是proto2的语法。这个语句必须出现在.proto文件的非空非注释的第一行。


[*]package user;
编译完成之后,包名为user


[*]service 定义服务
service UserService {
rpc Login(LoginRequest) returns (LoginResponse);
}

[*]message 定义结构体
message LoginRequest {
        string username=1;
        string password=2;
}数据类型


[*]strings 默认值是空字符串
[*]int32 默认是0(编译之后为go语言中的int类型)
[*]int64 默认是0 (编译之后为go语言中的int64)
[*]float 默认为0.0 (编译之后为go语言中的 float32)
[*]double 默认为0.0 (编译之后为go语言中的 float64)
[*]uint32 (编译之后为go语言中的 uint32)
[*]uint64 (编译之后为go语言中的 uint64)
[*]bytes 默认值是空bytes
[*]bool 默认值是false
[*]enum 默认值是第一个枚举值(value必须为0)
字段修饰符


[*]repeated:用来定义数组,一个字段可以重复出现一定次数(包括零次)
[*]required:值不可为空 (proto3中已删除)
[*]optional:可选字段 (proto3中已删除)
[*]singular:符合语法规则的消息包含零个或者一个这样的字段 (proto3中已删除)
[*]默认值: string code=2 ; (proto3中已删除)
[*]预留字段:reserved 6 to 8;
其他类型


[*]枚举定义
//枚举类型,必须从0开始,序号可跨越。同一包下不能重名,所以加前缀来区别
enum Role {
        Role_Admin=0;
        Role_Guest=1;
        Role_User=2;
        Role_Other=9;
}
[*]Map类型
map<key_type, value_type> map_field = N; 其中key_type可以是任意Integer或者string类型(所以,除了floating和bytes的任意标量类型都是可以的)value_type可以是任意类型。
例如,如果你希望创建一个project的映射,每个Projecct使用一个string作为key
map<string, Project> projects = 3;示例

syntax="proto3";
package user;

service UserService{
        // 注册
        rpc Signup(SignupRequest) returns (SignupResponse);
}
// 定义错误枚举,必须从0开始
enum LoginError {
        //密码错误
        Error_Password=0;
        //用户名错误
        Error_UserName=1;
        //内部服务器错误
        Error_Server=9;
}
message ID {
        int32 id=1;
}

// 注册请求体
message SignupRequest {
        string username=1;
        string password=2;
        int32 code=3;
        // 数组
        repeated string hobby=4;
        // map
        map<string,string> maps = 5;
}
//注册响应体
message SignupResponse {
        ID id=1;
        int32 code=2 ;
        string msg=3;
}数据校验

插件地址及文档:https://github.com/envoyproxy/protoc-gen-validate
流的使用

rpc GetStatus (GetReq) return (stream GetResp);service实现
func (HelloService) GetStatus(req *pb.GetReq,stream pb.HelloService_GetStatusServer) err {
        for i:=0;i<10;i++{
                stream.Send(&pb.GetResp{
                        Status: i,
                })
                if err:=stream.Context().Err();err!=nil {
                        fmt.Println("客户端关闭流...")
                        return err
                }
        }
        return nil
}
使用grpc-web访问流: 文档:https://github.com/grpc/grpc-web
var helloService= new proto.mypackage.HelloServiceClient('http://localhost:8080');
var getReq= new proto.mypackage.GetReq();
getReq.setMessage(msg);
var metadata = {'custom-header-1': 'value1'};
var stream = helloService.getStatus(getReq, metadata);
stream.on('data', function(response) {
console.log(response.getStatus());
});
stream.on('status', function(status) {
console.log(status.code);
console.log(status.details);
console.log(status.metadata);
});
stream.on('end', function(end) {
// stream end signal
});



欢迎关注我微信公众号,一起学习编程

unityloverz 发表于 2021-11-23 06:41

请教一下,.proto文件在编译过后,message是类还是结构体

Ylisar 发表于 2021-11-23 06:45

结构体

kyuskoj 发表于 2021-11-23 06:50

多谢

kirin77 发表于 2021-11-23 06:58

proto3不是废弃default了吗?为什么示例里面还有default
[疑惑]

七彩极 发表于 2021-11-23 07:00

returns后面可以不要返回值吗
页: [1]
查看完整版本: protobuf文件使用详解