生成的代码(旧版非泛型)参考
生成的代码(旧版非泛型)参考
此页面描述了使用 grpc 插件,protoc-gen-go-grpc
,在编译带有 protoc
的 .proto
文件时生成的代码。
您可以在服务定义中找到如何在 .proto
文件中定义 gRPC 服务的方法。
线程安全:请注意,客户端 RPC 调用和服务器端 RPC 处理程序是线程安全的,并且旨在在并发的 goroutine 上运行。但也要注意,对于单个流,传入和传出的数据是双向的,但串行的;因此,例如,单个流不支持并发读取或并发写入(但读取与写入是安全并发的)。
生成的服务器接口上的方法
在服务器端,.proto
文件中的每个 service Bar
都会产生以下函数
func RegisterBarServer(s *grpc.Server, srv BarServer)
应用程序可以定义 BarServer
接口的具体实现,并通过使用此函数将其注册到 grpc.Server
实例(在启动服务器实例之前)。
一元方法
这些方法在生成的服务接口上具有以下签名
Foo(context.Context, *MsgA) (*MsgB, error)
在此上下文中,MsgA
是从客户端发送的 protobuf 消息,而 MsgB
是从服务器发回的 protobuf 消息。
服务器流式方法
这些方法在生成的服务接口上具有以下签名
Foo(*MsgA, <ServiceName>_FooServer) error
在此上下文中,MsgA
是来自客户端的单个请求,而 <ServiceName>_FooServer
参数表示 MsgB
消息的服务器到客户端的流。
<ServiceName>_FooServer
具有嵌入的 grpc.ServerStream
和以下接口
type <ServiceName>_FooServer interface {
Send(*MsgB) error
grpc.ServerStream
}
服务器端处理程序可以通过此参数的 Send
方法向客户端发送 protobuf 消息流。服务器到客户端流的结束由处理程序方法的 return
导致。
客户端流式方法
这些方法在生成的服务接口上具有以下签名
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)
。通过调用此 <ServiceName>_FooServer
参数上的 SendAndClose
方法发送来自服务器的单个响应消息。请注意,SendAndClose
必须调用一次且仅调用一次。
双向流式方法
这些方法在生成的服务接口上具有以下签名
Foo(<ServiceName>_FooServer) error
在此上下文中,<ServiceName>_FooServer
可用于访问客户端到服务器的消息流和服务器到客户端的消息流。<ServiceName>_FooServer
具有嵌入的 grpc.ServerStream
和以下接口
type <ServiceName>_FooServer interface {
Send(*MsgA) error
Recv() (*MsgB, error)
grpc.ServerStream
}
服务器端处理程序可以重复调用此参数上的 Recv
,以便读取客户端到服务器的消息流。一旦到达客户端到服务器流的末尾,Recv
将返回 (nil, io.EOF)
。通过重复调用此 ServiceName>_FooServer
参数上的 Send
方法发送响应的服务器到客户端消息流。服务器到客户端流的结束由双向方法处理程序的 return
指示。
生成的客户端接口上的方法
对于客户端使用,.proto
文件中的每个 service Bar
也会产生以下函数:func BarClient(cc *grpc.ClientConn) BarClient
,它返回 BarClient
接口的具体实现(此具体实现也位于生成的 .pb.go
文件中)。
一元方法
这些方法在生成的客户端存根上具有以下签名
(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (*MsgB, error)
在此上下文中,MsgA
是从客户端到服务器的单个请求,而 MsgB
包含从服务器发回的响应。
服务器流式方法
这些方法在生成的客户端存根上具有以下签名
Foo(ctx context.Context, in *MsgA, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
在此上下文中,<ServiceName>_FooClient
表示 MsgB
消息的服务器到客户端的 stream
。
此流具有嵌入的 grpc.ClientStream
和以下接口
type <ServiceName>_FooClient interface {
Recv() (*MsgB, error)
grpc.ClientStream
}
当客户端在存根上调用 Foo
方法时,流开始。然后,客户端可以重复调用返回的 <ServiceName>_FooClient
流上的 Recv
方法,以便读取服务器到客户端的响应流。一旦服务器到客户端的流被完全读取完毕,此 Recv
方法将返回 (nil, io.EOF)
。
客户端流式方法
这些方法在生成的客户端存根上具有以下签名
Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
在此上下文中,<ServiceName>_FooClient
表示从客户端到服务器的 MsgA
消息的流
。
<ServiceName>_FooClient
包含一个嵌入的 grpc.ClientStream
以及以下接口
type <ServiceName>_FooClient interface {
Send(*MsgA) error
CloseAndRecv() (*MsgB, error)
grpc.ClientStream
}
当客户端在存根上调用 Foo
方法时,流开始。然后,客户端可以重复调用返回的 <ServiceName>_FooClient
流上的 Send
方法,以便发送客户端到服务器的消息流。必须调用此流上的 CloseAndRecv
方法一次且仅一次,以便同时关闭客户端到服务器的流并接收来自服务器的单个响应消息。
双向流式方法
这些方法在生成的客户端存根上具有以下签名
Foo(ctx context.Context, opts ...grpc.CallOption) (<ServiceName>_FooClient, error)
在此上下文中,<ServiceName>_FooClient
表示客户端到服务器和服务器到客户端的消息流。
<ServiceName>_FooClient
包含一个嵌入的 grpc.ClientStream
以及以下接口
type <ServiceName>_FooClient interface {
Send(*MsgA) error
Recv() (*MsgB, error)
grpc.ClientStream
}
当客户端在存根上调用 Foo
方法时,流开始。然后,客户端可以重复调用返回的 <SericeName>_FooClient
流上的 Send
方法,以便发送客户端到服务器的消息流。客户端还可以重复调用此流上的 Recv
方法,以便接收完整的服务器到客户端的消息流。
服务器到客户端流的流结束由流的 Recv
方法上的返回值 (nil, io.EOF)
指示。客户端到服务器流的流结束可以通过客户端调用流上的 CloseSend
方法来指示。
包和命名空间
当使用 --go_out=plugins=grpc:
调用 protoc
编译器时,proto package
到 Go 包的转换与不使用 grpc
插件而使用 protoc-gen-go
插件时的转换方式相同。
例如,如果 foo.proto
声明自己属于 package foo
,那么生成的 foo.pb.go
文件也将属于 Go package foo
。