演示 定义和编写proto文件
创建 string.proto 文件
在proto文件中使用 package 关键字声明包名,默认转换成 go 中的包名与此一致,如果需要指定不一样的包名,可以使用go_package 选项。
示例解释:option go_package="./;main"
是指生成的文件要放在 当前目录,main指生成的文件包名是main。
1、测试转换示例
syntax = "proto3";
package pb;
option go_package = "./pb";
service StringService{
rpc Concat(StringRequest) returns (StringResponse) {}
rpc Diff(StringRequest) returns (StringResponse) {}
}
message StringRequest {
string A = 1;
string B = 2;
}
message StringResponse {
string Ret = 1;
string err = 2;
}
进行转换
protoc --go_out=plugins=grpc:. pb/string.proto
转换成功后,会在pb目录下生成 string.pb.go 文件,结果如下:
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type StringRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
A string `protobuf:"bytes,1,opt,name=A,proto3" json:"A,omitempty"`
B string `protobuf:"bytes,2,opt,name=B,proto3" json:"B,omitempty"`
}
//...... 省略
2、测试 Message 示例:
proto
中的message
对应go中的struct
,全部使用驼峰命名规则。嵌套定义的message,enum转换为go之后,名称变为Parent_Child
结构。
示例 proto:
// Test 测试
message Test {
int32 age = 1;
int64 count = 2;
double money = 3;
float score = 4;
string name = 5;
bool fat = 6;
bytes char = 7;
// Status 枚举状态
enum Status {
OK = 0;
FAIL = 1;
}
Status status = 8;
// Child 子结构
message Child {
string sex = 1;
}
Child child = 9;
map<string, string> dict = 10;
}
转换结果:
// Status 枚举状态
type Test_Status int32
const (
Test_OK Test_Status = 0
Test_FAIL Test_Status = 1
)
// Test 测试
type Test struct {
Age int32 `protobuf:"varint,1,opt,name=age" json:"age,omitempty"`
Count int64 `protobuf:"varint,2,opt,name=count" json:"count,omitempty"`
Money float64 `protobuf:"fixed64,3,opt,name=money" json:"money,omitempty"`
Score float32 `protobuf:"fixed32,4,opt,name=score" json:"score,omitempty"`
Name string `protobuf:"bytes,5,opt,name=name" json:"name,omitempty"`
Fat bool `protobuf:"varint,6,opt,name=fat" json:"fat,omitempty"`
Char []byte `protobuf:"bytes,7,opt,name=char,proto3" json:"char,omitempty"`
Status Test_Status `protobuf:"varint,8,opt,name=status,enum=test.Test_Status" json:"status,omitempty"`
Child *Test_Child `protobuf:"bytes,9,opt,name=child" json:"child,omitempty"`
Dict map[string]string `protobuf:"bytes,10,rep,name=dict" json:"dict,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
// Child 子结构
type Test_Child struct {
Sex string `protobuf:"bytes,1,opt,name=sex" json:"sex,omitempty"`
}
除了会生成对应的结构外,还会有些工具方法,如字段的getter:
func (m *Test) GetAge() int32 {
if m != nil {
return m.Age
}
return 0
}
枚举类型会生成对应名称的常量,同时会有两个map方便使用:
var Test_Status_name = map[int32]string{
0: "OK",
1: "FAIL",
}
var Test_Status_value = map[string]int32{
"OK": 0,
"FAIL": 1,
}
3、测试 Service
定义一个简单的Service,TestService有一个方法Test,接收一个Request参数,返回Response:
// TestService 测试服务
service TestService {
// Test 测试方法
rpc Test(Request) returns (Response) {};
}
// Request 请求结构
message Request {
string name = 1;
}
// Response 响应结构
message Response {
string message = 1;
}
转换结果:
// 客户端接口
type TestServiceClient interface {
// Test 测试方法
Test(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
// 服务端接口
type TestServiceServer interface {
// Test 测试方法
Test(context.Context, *Request) (*Response, error)
}
生成的go代码中包含该Service定义的接口,客户端接口已经自动实现了,直接供客户端使用者调用,服务端接口需要由服务提供方实现。
作者:joker.liu 创建时间:2023-05-18 16:16
最后编辑:joker.liu 更新时间:2023-05-22 15:16
最后编辑:joker.liu 更新时间:2023-05-22 15:16