Grpc-Gateway 初体验

Posted 哥哥的激光炮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grpc-Gateway 初体验相关的知识,希望对你有一定的参考价值。

文件结构:

├── bin├── README.md├── controller│ └── mastiff.go├── example│ └── client.go├── go.mod├── go.sum├── main.go├── makefile├── proto └── mastiff.proto

Protobuf3 语法

proto3简介[1]

syntax = "proto3";
package pb_mastiff;option go_package = "proto;mastiff";
import "google/api/annotations.proto";
// 创建Idmessage CreateIdReq { string Prefix = 1;}
message CreateIdRes { string Data = 1;}
service Mastiff { rpc createId(CreateIdReq) returns (CreateIdRes){ option (google.api.http) = { post: "/v1/createId" body: "*" }; }}

1.第一行syntax用来指定 pb版本,必须位于第一行,不添加默认为protobuf22.消息体定义由 message开始; 参数建议使用下划线分割; 每个参数需要添加唯一编号,用于标识消息二进制格式字段label 默认使用 singular(0-1次), repeated(0-n次) optionalrequired被弃用。3.注释使用 // 或 /* ... */4.更新消息类型过程中,切勿删除现有字段与字段编号,使用保留字段reserved, 直接删除或后面重用该字段,可能会导致各种问题。5.参数类型为枚举类型,枚举需要从0开始。6.其他消息类型,可嵌套使用,如要在父消息类型外使用, 则使用 _Parent_._Type_7.导入其他消息类型,可使用import 关键字, 若引入文件目录不确定,则直接引用pb文件,编译期间使用-I/--proto_path是更好的选择。pb2与pb3可互相引用,但是不能在proto3语法中使用proto2枚举。8.package 用于防止出现命名冲突,相当于一个命名空间的作用9.option 的go_package 用于声明生成的go代码package 包名。option go_package > package > 文件名

pb编译

protobuf简介[2]

pb在Mac环境下,golang语言的使用

1.安装protobuf

brew install protobuf


2.安装golang代码生成依赖

go get -u -v github.com/golang/protobuf/protogo get -u -v github.com/golang/protobuf/protoc-gen-gogo get -u -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gatewaygo get -u -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger

    3.makefile 如下:

--proto_path= 或 -I :用于指定proto依赖。grpc-gateway 文件根据不同版本,可能需要调整其路径

--xx_out= : 根据我们上面安装protoc-gen-xx, 生成对应的xx文件。



 .PHONY:all all:clean build compile
build: protoc --proto_path=../ -I/usr/local/include -I. -I$(GOPATH)/pkg/mod -I$(GOPATH)/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.15.2/third_party/googleapis --go_out=plugins=grpc:. proto/mastiff.proto protoc --proto_path=../ -I/usr/local/include -I. -I$(GOPATH)/pkg/mod -I$(GOPATH)/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.15.2/third_party/googleapis --grpc-gateway_out=logtostderr=true:. proto/mastiff.proto protoc --proto_path=../ -I/usr/local/include -I. -I$(GOPATH)/pkg/mod -I$(GOPATH)/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.15.2/third_party/googleapis --swagger_out=logtostderr=true:. proto/mastiff.proto
compile: GOOS=darwin GOARCH=amd64 go build -o bin/mac_amd64 main.go GOOS=linux GOARCH=amd64 go build -o bin/linux_amd64 main.go
clean: rm -rf ./proto/*.go ./proto/*.json ./bin

4. 执行make,生成对应文件

 make


RPC服务与Gateway服务

启动service

分别启动rpchttp服务

go run main.go rpcgo run main.go http

调用RPC

go run example/client.go

调用Http

curl --location --request POST 'localhost:1728/v1/createId' \--header 'Content-Type: application/json' \--data-raw '{"Prefix": "dml:"}'

代码

controller/mastiff

package controller
import ( "context" pb "mastiff/proto")
type Service struct{}
// 创建IDfunc (s Service) CreateId(ctx context.Context, req *pb.CreateIdReq) (*pb.CreateIdRes, error) { return &pb.CreateIdRes{ Data: req.Prefix + "123456", }, nil}

main.go

package main
import ( "context" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/urfave/cli" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "log" "mastiff/controller" pb "mastiff/proto" "net" "net/http" "os" "sort")
const ( RpcPort = ":1718" HttpPort = ":1728")
func main() { mastiff := cli.NewApp() mastiff.Name = "controller" mastiff.Version = "1.0.0" mastiff.Email = "shanquan54@gmail.com" mastiff.Usage = "用于Token管理,Auth授权检测的服务系统" mastiff.Commands = []cli.Command{ { Name: "http", Usage: "http 服务", Description: "启动http服务", Action: httpServe, }, { Name: "rpc", Usage: "rpc 服务", Description: "启动rpc服务", Action: rpcSereve, }, } sort.Sort(cli.FlagsByName(mastiff.Flags)) sort.Sort(cli.CommandsByName(mastiff.Commands)) err := mastiff.Run(os.Args) if err != nil { log.Fatal(err.Error()) }}
func httpServe(c *cli.Context) { ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel()
mux := runtime.NewServeMux() opts := []grpc.DialOption{grpc.WithInsecure()} err := pb.RegisterMastiffHandlerFromEndpoint(ctx, mux, RpcPort, opts) if err != nil { log.Fatal(err) } log.Print("Listen Rpc Service: " + RpcPort) log.Print("init Http Service: " + HttpPort) if err := http.ListenAndServe(HttpPort, mux); err != nil { log.Fatal("Http Gateway failed") }}
func rpcSereve(c *cli.Context) {
// 启动服务监听 lis, err := net.Listen("tcp", RpcPort) if err != nil { log.Fatal(err) } s := grpc.NewServer(grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( grpc_recovery.UnaryServerInterceptor(), ))) pb.RegisterMastiffServer(s, &controller.MastiffService{}) reflection.Register(s)
log.Print("init Rpc Service: " + RpcPort) if err := s.Serve(lis); err != nil { log.Fatal("Rpc failed") }}

example/client.go

package main
import ( "context" "google.golang.org/grpc" "log" pb "mastiff/proto")
func main() { conn, err := grpc.Dial(":1718", grpc.WithInsecure()) if err != nil { log.Fatal(err) } mastiff := pb.NewMastiffClient(conn)
data, err := mastiff.CreateId(context.Background(), &pb.CreateIdReq{Prefix: "dml:"}) if err != nil { log.Fatal(err) } log.Print(data)}

References

[1] proto3简介:  https://developers.google.com/protocol-buffers/docs/proto3#simple

[2] protobuf简介:  https://github.com/protocolbuffers/protobuf


以上是关于Grpc-Gateway 初体验的主要内容,如果未能解决你的问题,请参考以下文章

python初体验

Flutter学习-flutter开发初体验

Django 代码初体验

结对编程初体验——代码复审

Qt for Python 5.12初体验

Kotlin初体验