go18/skills/rpc/protobuf/README.md

4.5 KiB
Raw Blame History

protobuf

// RPC 协议,约束服务端的实现,约束 客户端的调用
type HelloService interface {
	Hello(ctx context.Context, request string) (string, error)
}
  • RPC方法的定义
  • PRC数据结构的定义

安装vsocde的 proto语法高亮插件: vscode-proto3

插件安装

➜  protobuf go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go: downloading google.golang.org/protobuf v1.36.8
➜  protobuf go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go: downloading google.golang.org/grpc v1.75.0

接口声明

syntax = "proto3";

package hello;
option go_package="122.51.31.227/go-course/go18/skills/rpc/protobuf/hello_service";

// The HelloService service definition.
service HelloService {
    // rpc 声明接口
    rpc Hello (Request) returns (Response);
}

message Request {
    string value = 1;
}

message Response {
    string value = 1;
}

使用protobuf 定义数据结构

使用protoc-gen-go 插件来生成struct

message Request {
    string value = 1;
}

message Response {
    string value = 1;
}
# -- go_out 是参数, go out: go使用go语言插件(protoc-gen-go), go语言插件的参数 out
# out: 生成的代码放哪个目录, 默认项目根目录
# opt: module="xxx", 用于指定文件所属go module
# 应用使用了module="xxx"最好在工程根目录执行
# -I: 指定protobuf include的其他包的搜索位置, 通常情况 项目根目录比较合适
# cd go18
protoc -I=. --go_out=. --go_opt=module="122.51.31.227/go-course/go18" skills/rpc/protobuf/hello_service/interface.proto 

interface.pb.go

type Request struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Value         string                 `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

type Response struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Value         string                 `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

使用protobuf 定义RPC (grpc)

使用 protoc-gen-go-grpc来生成 接口描述(service定义相关部分)

// The HelloService service definition.
service HelloService {
    // rpc 声明接口
    rpc Hello (Request) returns (Response);
}
# -- go_out 是参数, go out: go使用go语言插件(protoc-gen-go), go语言插件的参数 out
# out: 生成的代码放哪个目录, 默认项目根目录
# opt: module="xxx", 用于指定文件所属go module
# 应用使用了module="xxx"最好在工程根目录执行
# -I: 指定protobuf include的其他包的搜索位置, 通常情况 项目根目录比较合适
# cd go18
protoc -I=. --go-grpc_out=. --go-grpc_opt=module="122.51.31.227/go-course/go18" skills/rpc/protobuf/hello_service/interface.proto 

interface_grpc.pb.go

// 服务端接口
// HelloServiceServer is the server API for HelloService service.
// All implementations must embed UnimplementedHelloServiceServer
// for forward compatibility.
//
// The HelloService service definition.
type HelloServiceServer interface {
	// rpc 声明接口
	Hello(context.Context, *Request) (*Response, error)
	mustEmbedUnimplementedHelloServiceServer()
}

// 客户端接口
// HelloServiceClient is the client API for HelloService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
//
// The HelloService service definition.
type HelloServiceClient interface {
	// rpc 声明接口
	Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}

// 客户端的具体实现
type helloServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewHelloServiceClient(cc grpc.ClientConnInterface) HelloServiceClient {
	return &helloServiceClient{cc}
}

func (c *helloServiceClient) Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
	out := new(Response)
	err := c.cc.Invoke(ctx, HelloService_Hello_FullMethodName, in, out, cOpts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

服务端实现接口注册给grpc服务

其他服务 使用生成的client调用grpc服务的方法

protoc -I=. --go_out=. --go_opt=module="122.51.31.227/go-course/go18" skills/rpc/protobuf/app_service/interface.proto