生成代码(遗留的非泛型)参考
生成的服务器接口的方法
在服务器端,.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
方法来发送。服务器到客户端流的结束由双向方法处理程序的返回表示。
生成的客户端接口的方法
对于客户端使用,每个 .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
消息流。
此流包含一个嵌入式的 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
方法时,流开始。然后,客户端可以在返回的 <ServiceName>_FooClient
流上重复调用 Send
方法,以发送客户端到服务器的消息流。客户端还可以在此流上重复调用 Recv
方法,以接收完整的服务器到客户端的消息流。
服务器到客户端流的结束通过 Recv
方法返回 (nil, io.EOF)
来指示。客户端到服务器流的结束可以通过客户端调用流上的 CloseSend
方法来指示。