go18/skills/rpc/protobuf/README.md
2025-08-24 11:35:52 +08:00

158 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# protobuf
```go
// RPC 协议,约束服务端的实现,约束 客户端的调用
type HelloService interface {
Hello(ctx context.Context, request string) (string, error)
}
```
+ RPC方法的定义
+ PRC数据结构的定义
## 插件安装
```sh
➜ 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
```
## 接口声明
```proto
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
```proto
message Request {
string value = 1;
}
message Response {
string value = 1;
}
```
```sh
# -- 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
```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定义相关部分)
```proto
// The HelloService service definition.
service HelloService {
// rpc 声明接口
rpc Hello (Request) returns (Response);
}
```
```sh
# -- 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
```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服务的方法