gPPC 生成 Go 代码参考文档
Table of Contents
https://grpc.io/docs/reference/go/generated-code/
生成 Go 的 protobuf package 文件需要在使用 protoc 编译 .proto
文件时使用 protoc-gen-go
插件。
1. 命令行
使用 protobuf 编译器:
protoc -I=libproto --go_out=plugins=grpc:libproto libproto/xxx.proto
2. 服务器接口生成的方法
在 Server 端, .proto
文件中的每一个 service Bar
都会生成如下的函数:
func RegisterBarServer(s *grpc.Server, svr BarServer)
在服务器启动之前,应用程序要自己实现一个 BarServer
接口的具体实现,然后把它注册到 grpc.Server
实例中。
2.1. 一元方法(Unary methods)
这些方法在生成服务接口的时候有如下的签名:
Foo(context.Context, *MsgA) (*MsgB, error)
MsgA
是客户端请求的 protobuf 消息, MsgB
是从服务器返回的 protobuf 消息。
2.2. 服务器流方法(Server-streaming methods)
这些方法在生成服务接口的时候有如下的签名:
Foo(*MsgA, <ServiceName>_FooServer) error
MsgA
是来自客户端的单个请求, <ServiceName>_FooServer
表示 MsgB
的 server-to-client流。
<ServiceName>_FooServer
是一个内嵌 grpc.ServerStream
的如下接口:
type <ServiceName>_FooServer interface { Send(*MsgB) error grpc.ServerStream }
服务端的处理器通过 Send
方法向客户端不断的发送 protobuf 消息,流的结束以处理器的 handler
方法为准。
2.3. 客户端流方法(Client-streaming methods)
这些方法在生成服务接口的时候有如下的签名:
Foo(<ServiceName>_FooServer) error
<ServiceName>_FooServer
既可以用来读取从客户端到服务器的消息流,也可以用来发送单个服务器的响应消息。
<ServiceName>_FooServer
是一个内嵌 grpc.ServerStream
的如下接口:
type <ServiceName>_FooServer interface { SendAndClose(*MsgA) error Recv() (*MsgB, error) grpc.ServerStream }
服务端可以重复的调用 Recv
来获取从客户端发送过来的全部消息。 Recv
一旦返回 (nil, io.EOF)
说明流结束了。
服务端回复消息通过调用 SendAndClose
方法。注意 SendAndClose
只能被调用一次。
2.4. 双向流(Bidi-streaming methods)
这些方法在生成服务接口的时候有如下的签名:
Foo(<ServiceName>_FooServer) error
<ServiceName>_FooServer
既可以访问从客户端到服务器的流也可以访问从服务器到客户端的流。 <ServiceName>_FooServer
内嵌了
grpc.ServerSteam
如下:
type <ServiceName>_FooServer interface { Send(*MsgA) error Recv() (*MsgB, error) grpc.ServerStream }
服务器端的处理程序可以重复调用 Recv
获取从客户端发来的消息流。 Recv
返回 (nil, io.EOF)
表示客户端流结束了。
回复的流通过重复调用 Send
方法来实现, return
表示发送结束。
3. 客户端接口生成的方法
在客户端测, proto
文件中的每一个 service Bar
也都会生成一个函数: func BarClient(cc *grpc.ClientConn) BarClient
,
它会返回 BarClient
接口的具体实现(此接口实现也会存在于生成的 .pb.go
文件中)。
3.1. 一元方法(Unary Methods)
这些方法生成的客户端存根具有以下签名:
(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (*MsgB, error)
MsgA
是客户端的请求, MsgB
是服务器的回包。
3.2. 服务端流方法(Server-Streaming methods)
这些方法生成的客户端存根具有以下签名:
Foo(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
<ServiceName>_FooClient
表示服务器到客户端的 MsgB
的消息流。该流是由内嵌一个 gprc.ClientStream
的接口:
type <ServiceName>_FooClient interface { Recv() (*MsgB, error) grpc.ClientStream }
客户端重复调用 Recv
方法来返回服务器回复的消息。当 Recv
接受到 (nil, io.EOF)
表示流结束。
3.3. 客户端流方法(Client-Streaming methods)
这些方法生成的客户端存根具有以下签名:
Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
<ServieName>_FooClient
表示客户端到服务器的 MsgA
消息流。
<ServieName>_FooClient
是一个内嵌了 grpc.ClientStream
的如下接口:
type <ServiceName>_FooClient interface { Send(*MsgA) error CloseAndRecv() (*MsgA, error) grpc.ClientStream }
客户端可以重复调用 Send
方法想服务器发送消息,最后调用 CloseAndRecv()
结束发送等待服务器回包。
3.4. 双向流方法(Bidi-Streaming methods)
这些方法生成的客户端存根具有以下签名:
Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
<ServiceName>_FooClient
表示客户端到服务器和服务器到客户端的双向流。它是内嵌了 grpc.ClientStream
的如下接口:
type <ServiceName>_FooClient interface { Send(*MsgA) error Recv() (*MsgB, error) grpc.ClientStream }
客户端重复调用 Send
方法发送消息,同时可以重复调用 Recv
方法接受消息。
服务器到客户端的流通过返回 (nil, io.EOF)
终结,客户端到服务器的流通过客户端调用 CloseSend
来结束。
4. 包和命名空间
当 protoc
编译器调用 -go_out=plugins=grpc:
时, proto package
会被转换成 Go 的包,跟 protoc-gen-go
插件不加 grpc
效果相同。
因此,如果 foo.proto
在 package foo
中声明,那么 foo.pb.go
生成的文件也会在 Go 的包 foo
包中。