grpc.v2

前述

golang grpc的API有2个版本:

从github.com/golang/protobuf@v1.4.0后, golang grpc的源码生成工具归属到grpc-go的repository, 即所谓的v2版本. 以前用"protoc --go_out=plugins=grpc..."生成grpc的rpc stup代码, 现在要用"protoc --go_out=... --go-grpc_out=..."生成grpc的rpc stup代码!

新的protoc-gen-go插件已经不支持plugins选项:

--go_out: protoc-gen-go: plugins are not supported; use 'protoc --go-grpc_out=...' to generate gRPC

参考

实践

下载工具

windows:

set GO111MODULE=on
set GOPROXY=https://goproxy.cn
go get google.golang.org/protobuf google.golang.org/grpc
go install google.golang.org/protobuf/cmd/protoc-gen-go google.golang.org/grpc/cmd/protoc-gen-go-grpc

或者

set GO111MODULE=on
set GOPROXY=https://goproxy.cn
go get google.golang.org/protobuf/cmd/protoc-gen-go google.golang.org/grpc/cmd/protoc-gen-go-grpc

注意: go get实际等价于"git clone + go install", 如果package有main则会直接安装到bin. 因此只需将$GOPATH/bin添加PATH即可!

生成代码

  • 编辑proto
syntax = "proto3";

package api;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // Sends another greeting
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
  • 执行protoc
protoc --go_out=. --proto_path=. greeter.proto
protoc --go-grpc_out=. --proto_path=. greeter.proto

或者

protoc --go_out=. --go-grpc_out=. --proto_path=. greeter.proto
  • 查看files
grpc-v2
 |__api
    |__greeter.pb.go
    |__greeter.proto
    |__greeter_grpc.pb.go

可见,之前grpc代码已经生成到_grpc.pb.go文件

创新

<file>_$GOOS_$GOARCH.go
  • build constraints
// +build linux
// +build go1.8
// +build !go1.8
...

注意: golang的build constraints必须位于package前面, 而且与首条package之间保持至少一个空行! 否则会被认为是package的comment, 而不是file comment!

  • 实现protobuf的build constraints

    • 以+打头的comment
    • file, package, message/field, service/method
  • 实际需求

    • 在message上标上"+content-type application/json"或"+content-type multipart/form-data".
    // +content-type multipart/form-data
    message HelloReq {
        // +form-file
        string upload_file = 1; 
        ...
    }
    
    service Greeter {
        // +http-path /demo/hello
        rpc SayHello (HelloRequest) returns (HelloReply);
    }
    
    如果在message标上"+content-type multipart/form-data",则会按照form形式去解析, 各个字段根据field_name去解析相应的值. 默认是"application/json"!
    

    可以考虑使用更短的命名: "+type form", "+type json", "+file", "+path /demo/hello"等等!
    这些build constraints会影响产生的http代码!

    • 在service使用辅助API获取相应的值
    ProtoKit.File(ctx, req.upload_file): name, size, reader
    
    • 生成文件命名形式, 参考grpc生成文件: "_http.pb.go", 所以build contstraints统一加上http前缀是否会更清楚!
    +http-type: from // multipart/form-data
    +http-type: json // application/json(默认!)
    +http-file // 标记字段是form-file获取, 可以使用ProtoKit.File()提取相关的临时文件
    +http-path path // 标记service.method的http-path!
    
  • 如何实现
    • 将proto中的所有message/service都扫描到metadata中.
    • 提供统一的数据结构, 可以template渲染, 也可以programma渲染!
posted @ 2020-11-23 15:00  zolo®  阅读(142)  评论(0编辑  收藏  举报