弑君者

V1

2023/01/20阅读:19主题:默认主题

rpc和grpc

什么是grpc和protobuf

grpc: grpc 是一个高性能、开源和通用的RPC框架,面向移动和HTTP/2的设计。

protobuf: 就是一种数据传输协议,有点类似json或者xml。

protobuf的基本类型

  1. 定义一个消息类型
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);
}

  1. proto文件引入另一个proto文件

直接通过import 引入就可以,比如

import "base.proto"
  1. 嵌套的message

message StreamReq {
  string id = 1;
  
  message req {
    string name = 1;
  }
}

  1. 枚举类型
enum Gender {
  MALE = 0;
  FEMALE = 1;
}

message HelloRes {
  string name = 1;
  string url = 2;
  // 枚举类型
  Gender g = 3;
}

  1. Map 类型
message StramRes {
  string data = 1;
  map<string,string> mp=2;
}

  1. go控制grpc的metadata

metadata是以key和value方式存储的

  1. 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);

  1. 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}];
  }
}
  1. grpc的状态码

实际开发的时候,还可以自己定义状态码

返回错误状态码

status.Errorf(codes.NotFound, "记录未找到:%s", request.Name)

解析错误状态码

st, ok := status.FromError(err)
  1. grpc的超时设置

如果客户端去访问服务端的时候,需要设置超时时间,类似axios的timeout设置。

使用context.WithTimeout就可以

ctx, _ := context.WithTimeout(context.Background(), time.Second*3)

分类:

后端

标签:

后端

作者介绍

弑君者
V1