在与 grpc.ClientStreams 交互时是否需要调用 Recv 直到获得 io.EOF?

Are you required to call Recv until you get io.EOF when interacting with grpc.ClientStreams?

假设我定义了以下 gRPC 服务:

service Library {
  rpc Search(SearchBookRequest) returns (stream SearchBookResponse) {} 
}

message SearchBookRequest {
  string term = 1;
  int32 max_results = 2;
}

message SearchBookResponse {
  int32 book_id = 1;
}

它将搜索结果流式传输到指定的最大值。当通过 gRPC 的 Go API 与服务交互时,我可以做这样的事情吗?

for i:=0; i<maxResults; i++ {
  search_result, err := stream.Recv()
  if err == io.EOF {
    // Note: If `maxResults` are returned this will never be reached.
    break
  }
  if err != nil {
    log.Fatalf("search error: %v", err)
  }
  fmt.Printf("Book-ID: %d\n", search_result.BookId)
}

或者我是否需要继续调用 Recv 直到我得到 io.EOF 以确保 gRPC 正确清理其所有资源?

您的代码是正确的。

您可以在出现错误时退出。您无需等待 EOF。


编辑:以上答案不完整。

调用者应该一直接收直到出错,否则可能会泄露。还有其他方法可以避免泄漏,例如取消上下文。有关详细信息,请参阅 https://pkg.go.dev/google.golang.org/grpc#ClientConn.NewStream