1、前提
已安装好golang,并开启go mod,同时设置golang的国内镜像
2、安装protoc 3.13.0
下载链接:https://github.com/protocolbuffers/protobuf/releases/tag/v3.13.0
下载相应平台安装包
3、为protoc安装go语言插件,安装grpc-gateway V1版本
在命令行中,执行以下命令:
go install go install github.com/grpc-ecosystem/grpc-gateway/tree/v1.16.0/protoc-gen-grpc-gateway@latest
github.com/grpc-ecosystem/grpc-gateway/tree/v1.16.0/protoc-gen-swagger@latest
github.com/golang/protobuf/protoc-gen-go@latest
4、生成 gRPC 代码
- 新建proto文件: trip.proto
syntax="proto3";
package coolcar;
option go_package="coolcar/proto/gen/go;trippb";
其中 option go_package="coolcar/proto/gen/go;trippb";
coolcar/proto/gen/go:表示生成的文件存放目录
trippb:表示生成的go文件包的名字
建议:
包名称:trippb
proto文件名称为:trip.proto
两者名字前缀最好要一致。
- 建立三个message,同时包含复合类型(Location)和枚举类型(TripStatus)以及repeated重复类型
syntax="proto3";
package coolcar;
option go_package="coolcar/proto/gen/go;trippb";
message Location {
double latitude = 1;
double longitude = 2;
}
enum TripStatus {
TS_NOT_SPECIFIED = 0;
NOT_STARTED = 1;
IN_PROGRESS = 2;
FINISHED = 3;
PAID = 4;
}
message Trip {
string start = 1;
string end = 2;
Location start_pos = 5;
Location end_pos = 6;
repeated Location path_locations = 7;
int64 duration_sec = 3;
int64 fee_cent = 4;
TripStatus status = 8;
}
- 运行以下命令
protoc -I=. --go_out=paths=source_relative:gen/go trip.proto
生成trip.pb.go文件
可以看出,其中proto中的double类型转换为golang的float64,枚举类型转换为int32,复合类型为指针类型,repeated类型转换为指针切片。
5、运行实例
package main
import "fmt"
import "encoding/json"
import trippb "coolcar/proto/gen/go"
import "google.golang.org/protobuf/proto"
func main() {
trip := trippb.Trip{
Start:"abc",
End:"end",
DurationSec:3600,
FeeCent:10000,
StartPos:&trippb.Location{ //必须为取地址
Latitude:30,
Longitude:120,
},
EndPos:&trippb.Location{
Latitude:35,
Longitude:115,
},
PathLocations:[]*trippb.Location{ //指针切片
{
Latitude:31,
Longitude:119,
},
{
Latitude:32,
Longitude:118,
},
},
Status:trippb.TripStatus_IN_PROGRESS,
}
b,err := proto.Marshal(&trip) //序列化
if err != nil {
panic(err)
}
fmt.Printf("%X\n",b)
var trip2 trippb.Trip
err = proto.Unmarshal(b,&trip2) //反序列化
if err != nil {
panic(err)
}
fmt.Println(&trip2)
b,err = json.Marshal(&trip2)
if err != nil {
panic(err)
}
fmt.Printf("%s\n",b)
}
(1)关键在于此语句:
import trippb "coolcar/proto/gen/go"
与proto中的定义对应起来:option go_package="coolcar/proto/gen/go;trippb";
包名称为:trippb
包路径为:coolcar/proto/gen/go
(2)序列化:
b,err := proto.Marshal(&trip) //序列化
(3)反序列化
err = proto.Unmarshal(b,&trip2) //反序列化
(4)输出结果: