弑
弑君者
V1
2023/01/20阅读:31主题:默认主题
rpc和grpc
什么是grpc和protobuf
grpc: grpc 是一个高性能、开源和通用的RPC框架,面向移动和HTTP/2的设计。
protobuf: 就是一种数据传输协议,有点类似json或者xml。

protobuf的基本类型
-
定义一个消息类型
syntax = "proto3";
// 包名
package stream.v1;
// 指定目录和包名
option go_package="stream/api/gen/v1;proto";
message StreamReq {
// 1 表示顺序,不是值
string data = 1;
string add = 2;
}
message StramRes {
string data = 1;
}
service Greeter {
//
rpc NormalSteam(StreamReq) returns (StramRes);
// 服务端流模式
rpc GetStream(StreamReq) returns (stream StramRes);
// 客户端流模式
rpc PutStream(stream StreamReq) returns (StramRes);
// 双流模式
rpc AllStream(stream StreamReq) returns (stream StramRes);
}
-
proto文件引入另一个proto文件
直接通过import 引入就可以,比如
import "base.proto"
-
嵌套的message
message StreamReq {
string id = 1;
message req {
string name = 1;
}
}
-
枚举类型
enum Gender {
MALE = 0;
FEMALE = 1;
}
message HelloRes {
string name = 1;
string url = 2;
// 枚举类型
Gender g = 3;
}
-
Map 类型
message StramRes {
string data = 1;
map<string,string> mp=2;
}
-
go控制grpc的metadata
metadata是以key和value方式存储的
-
grpc 的拦截器
拦截器类似koa的中间件
服务端的拦截器
interceptor := func(ctx context.Context,req interface{}, info *grpc.UnaryServerInfo,handler grpc.UnaryHandler)(resp interface{},err error) {
fmt.Println("获取一个新的服务请求");
return handler(ctx,req)
}
opt := grpc.UnaryInterceptor(interceptor)
客户端的拦截器
interceptor := func(ctx context.Context,method string, req, reply interface{}, cc *grpc.ClientConn,invoke grpc.UnaryInvoker, opts ...grpc.CallOption)(error) {
start := time.Now();
err := invoke(ctx, method,req,reply,cc,opts...);
fmt.Println(time.Since(start));
return err;
}
opt := grpc.WithUnaryInterceptor(interceptor);
-
grpc 验证器
使用 protoc-gen-validate
syntax = "proto3";
package examplepb;
import "validate/validate.proto";
message Person {
uint64 id = 1 [(validate.rules).uint64.gt = 999];
string email = 2 [(validate.rules).string.email = true];
string name = 3 [(validate.rules).string = {
pattern: "^[^[0-9]A-Za-z]+( [^[0-9]A-Za-z]+)*$",
max_bytes: 256,
}];
Location home = 4 [(validate.rules).message.required = true];
message Location {
double lat = 1 [(validate.rules).double = {gte: -90, lte: 90}];
double lng = 2 [(validate.rules).double = {gte: -180, lte: 180}];
}
}
-
grpc的状态码

实际开发的时候,还可以自己定义状态码
返回错误状态码
status.Errorf(codes.NotFound, "记录未找到:%s", request.Name)
解析错误状态码
st, ok := status.FromError(err)
-
grpc的超时设置
如果客户端去访问服务端的时候,需要设置超时时间,类似axios的timeout设置。
使用context.WithTimeout就可以
ctx, _ := context.WithTimeout(context.Background(), time.Second*3)
作者介绍
弑
弑君者
V1