GRPC+Gateway配置与使用
前提需求:
可执行文件:
需要包括的可执行文件有:
protoc.exe
protoc-gen-go.exe
protoc-gen-grpc-gateway.exe
protoc-gen-swagger.exe
为方便使用,已经将四个exe文件打包为压缩包,并上传百度网盘
链接: https://pan.baidu.com/s/1F9updJQfuqSgvghrcODRbQ 提取码: ti5h
压缩包名字为 : GRPC_GATEWAY_所需的相关文件.zip
请将以上四个 exe 文件解压并放入 $PATH 目录下.
如果链接已经失效,或者想知道如何 自己手动build产生以上可执行文件, 请跳转至本文档的最后一章节.
依赖文件:
需要的依赖文件:
包括但不限于
annotations.proto
http.proto
descriptor.proto
...
为方便使用,已经将所需的依赖库文件打包为压缩包,并上传百度网盘
链接: https://pan.baidu.com/s/1F9updJQfuqSgvghrcODRbQ 提取码: ti5h
压缩包名字为 : GRPC_GATEWAY_所需的相关文件.zip
请将以上依赖库文件解压并放入C:/grpcgateway 目录下.
如果链接已经失效,或者想知道以上依赖文件的来源, 请跳转至本文档的最后一章节.
代码依赖库
go get -u google.golang.org/grpc
go get -u github.com/golang/protobuf/proto
go get -u github.com/grpc-ecosystem/grpc-gateway
编写一个*.proto接口文件
一个简单的同时支持GRPC和Gateway的例子:
syntax = "proto3";
package echo;
import "google/api/annotations.proto";
message StringMessage {
string value = 1;
}
service EchoService {
rpc Echo(StringMessage) returns (StringMessage) {
option (google.api.http) = {
post: "/v1/echo"
body: "*"
};
}
}
解读:
例子中,
1.package echo 是包名, 根据proto产生出来的代码文件,会以echo这个名字命名函数.
2.通过 message StringMessage {} 定义了一个数据类型(相当于结构体)
3.rpc Echo(StringMessage) returns (StringMessage) 定义了一个函数,其request格式和response格式都是StringMessage . 其中,需要在函数体内部, 规定 http方法,以及路由.
option (google.api.http) = {
post: “/v1/echo”
body: “*”
};规定了 http 方法是 post, 路由是 /v1/echo 要post的数据是 StringMessage
编译 *.proto 接口文件
首先打开 Powershell,或者 MINGW64 或者 Bash(Linux)
进入*.proto文件所在的文件夹
第一步,产生 grpc 对应的代码文件
在命令行输入
protoc -IC:/grpcgateway -I. \
--go_out=plugins=grpc:. \
./*.proto
命令行的解读:
第一行:规定了依赖库文件的目录地址,这里规定的目录地址是 C:/grpcgateway
第二行:规定了编译插件是grpc,输出的代码是golang
第三行:规定了*.proto文件的所在路径, 此命令表示在当前目录下寻找任意 *.proto文件
通过该命令即可产生 grpc 的 stub代码
第二步,产生 grpc gateway 对应的代码文件
在命令行输入
protoc -IC:/grpcgateway -I. \
--grpc-gateway_out=logtostderr=true:. \
./*.proto
命令行的解读:
第一行:规定了依赖库文件的目录地址,这里规定的目录地址是 C:/grpcgateway
第二行:规定了编译插件是grpc-gateway_out,输出的代码是golang
第三行:规定了*.proto文件的所在路径, 此命令表示在当前目录下寻找任意 *.proto文件
编译成功后,会产生的代码文件是:
编写GRPC的服务:
这里介绍的是最Basic的方式,可能有现有的框架以更优的方式来实现.
最朴素的,使用echo.pb.go 文件(GRPC的stub代码文件)的方式是:
对于服务端:
一个最朴素的代码
package main
import (
"log"
"net"
"golang.org/x/net/context"
"google.golang.org/grpc"
pb "test_grpc/gw/pb"
)
const (
port = ":51001"
)
type server struct {
}
func (s *server) Echo(c context.Context, v *pb.StringMessage) (*pb.StringMessage, error) {
result := &pb.StringMessage{
Value: v.Value}
return result, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// Creates a new gRPC server
s := grpc.NewServer()
pb.RegisterEchoServiceServer(s, &server{
})
s.Serve(lis)
}
代码解读:
- 在import中,通过 import pb “test_grpc/gw/pb” 将stub代码引入进来
- 使用 s := grpc.NewServer() 和 s.Serve(lis) 建立服