使用 C# 的 gRPC 服務
注意
這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支援原則。 如需目前版本,請參閱本文的 .NET 8 版本。
本文件概述以 C# 撰寫 gRPC 應用程式所需的概念。 此處涵蓋的主題適用於 C-core 型和 ASP.NET Core 型 gRPC 應用程式。
proto 檔案
gRPC 使用 API 開發的合約優先方法。 通訊協定緩衝區 (protobuf) 預設會作為介面定義語言 (IDL) 使用。 .proto
檔案包含:
- gRPC 服務的定義。
- 用戶端與伺服器之間傳送的訊息。
如需 protobuf 檔案語法的詳細資訊,請參閱為 .NET 應用程式建立 Protobuf 訊息。
例如,請考慮開始使用 gRPC 服務中使用的 greet.proto 檔案:
- 定義
Greeter
服務。 Greeter
服務定義SayHello
呼叫。SayHello
傳送HelloRequest
訊息並接收HelloReply
訊息:
syntax = "proto3";
option csharp_namespace = "GrpcGreeter";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
如果您想要查看翻譯為英文以外語言的程式碼註解,請在此 GitHub 討論問題中告訴我們。
將 .proto
檔案新增至 C# 應用程式
藉由將 .proto
檔案新增至 <Protobuf>
項目群組,即可將該檔案包含在專案中:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
根據預設,<Protobuf>
參考會產生具體的用戶端和服務基底類別。 參考元素的 GrpcServices
屬性可用來限制 C# 資產產生作業。 有效的 GrpcServices
選項如下:
Both
(不存在時的預設值)Server
Client
None
.proto
檔案的 C# 工具支援
需要工具套件 Grpc.Tools 才能從 .proto
檔案產生 C# 資產。 產生的資產 (檔案):
- 在每次建置專案時視需要產生。
- 不會新增至專案或簽入原始檔控制。
- 是 obj目錄中所包含的組建成品。
伺服器和用戶端專案都需要此套件。 Grpc.AspNetCore
中繼套件包含 Grpc.Tools
的參考。 伺服器專案可以使用 Visual Studio 中的套件管理員來新增 Grpc.AspNetCore
,或藉由將 <PackageReference>
新增至專案檔來新增:
<PackageReference Include="Grpc.AspNetCore" Version="2.32.0" />
用戶端專案應該直接參考 Grpc.Tools
,以及使用 gRPC 用戶端所需的其他套件。 執行階段不需要工具套件,因此相依性會標示為 PrivateAssets="All"
:
<PackageReference Include="Google.Protobuf" Version="3.18.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.40.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
產生的 C# 資產
工具套件會產生 C# 類型,代表在所包含 .proto
檔案中定義的訊息。
對於伺服器端資產,會產生抽象服務基底類型。 基底類型包含 .proto
檔案中內含的所有 gRPC 呼叫的定義。 建立衍生自此基底類型的具體服務實作,並實作 gRPC 呼叫的邏輯。 對於 greet.proto
(先前所述的範例),會產生包含虛擬 SayHello
方法的抽象 GreeterBase
類型。 具體實作 GreeterService
會覆寫該方法,並實作處理 gRPC 呼叫的邏輯。
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
對於用戶端資產,會產生具體的用戶端類型。 .proto
檔案中的 gRPC 呼叫會轉譯成可呼叫之具體類型的方法。 對於 greet.proto
(先前所述的範例),會產生具體的 GreeterClient
類型。 呼叫 GreeterClient.SayHelloAsync
以起始對伺服器的 gRPC 呼叫。
// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7042");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
根據預設,系統會針對 <Protobuf>
項目群組中包含的每個 .proto
檔案產生伺服器和用戶端資產。 為了確保只會在伺服器專案中產生伺服器資產,GrpcServices
屬性會設定為 Server
。
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
同樣地,該屬性會在用戶端專案中設定為 Client
。
其他資源
本文件概述以 C# 撰寫 gRPC 應用程式所需的概念。 此處涵蓋的主題適用於 C-core 型和 ASP.NET Core 型 gRPC 應用程式。
proto 檔案
gRPC 使用 API 開發的合約優先方法。 通訊協定緩衝區 (protobuf) 預設會作為介面定義語言 (IDL) 使用。 .proto
檔案包含:
- gRPC 服務的定義。
- 用戶端與伺服器之間傳送的訊息。
如需 protobuf 檔案語法的詳細資訊,請參閱為 .NET 應用程式建立 Protobuf 訊息。
例如,請考慮開始使用 gRPC 服務中使用的 greet.proto 檔案:
- 定義
Greeter
服務。 Greeter
服務定義SayHello
呼叫。SayHello
傳送HelloRequest
訊息並接收HelloReply
訊息:
syntax = "proto3";
option csharp_namespace = "GrpcGreeter";
package greet;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings.
message HelloReply {
string message = 1;
}
如果您想要查看翻譯為英文以外語言的程式碼註解,請在此 GitHub 討論問題中告訴我們。
將 .proto
檔案新增至 C# 應用程式
藉由將 .proto
檔案新增至 <Protobuf>
項目群組,即可將該檔案包含在專案中:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
根據預設,<Protobuf>
參考會產生具體的用戶端和服務基底類別。 參考元素的 GrpcServices
屬性可用來限制 C# 資產產生作業。 有效的 GrpcServices
選項如下:
Both
(不存在時的預設值)Server
Client
None
.proto
檔案的 C# 工具支援
需要工具套件 Grpc.Tools 才能從 .proto
檔案產生 C# 資產。 產生的資產 (檔案):
- 在每次建置專案時視需要產生。
- 不會新增至專案或簽入原始檔控制。
- 是 obj目錄中所包含的組建成品。
伺服器和用戶端專案都需要此套件。 Grpc.AspNetCore
中繼套件包含 Grpc.Tools
的參考。 伺服器專案可以使用 Visual Studio 中的套件管理員來新增 Grpc.AspNetCore
,或藉由將 <PackageReference>
新增至專案檔來新增:
<PackageReference Include="Grpc.AspNetCore" Version="2.28.0" />
用戶端專案應該直接參考 Grpc.Tools
,以及使用 gRPC 用戶端所需的其他套件。 執行階段不需要工具套件,因此相依性會標示為 PrivateAssets="All"
:
<PackageReference Include="Google.Protobuf" Version="3.11.4" />
<PackageReference Include="Grpc.Net.Client" Version="2.52.0" />
<PackageReference Include="Grpc.Tools" Version="2.28.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
產生的 C# 資產
工具套件會產生 C# 類型,代表在所包含 .proto
檔案中定義的訊息。
對於伺服器端資產,會產生抽象服務基底類型。 基底類型包含 .proto
檔案中內含的所有 gRPC 呼叫的定義。 建立衍生自此基底類型的具體服務實作,並實作 gRPC 呼叫的邏輯。 對於 greet.proto
(先前所述的範例),會產生包含虛擬 SayHello
方法的抽象 GreeterBase
類型。 具體實作 GreeterService
會覆寫該方法,並實作處理 gRPC 呼叫的邏輯。
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
對於用戶端資產,會產生具體的用戶端類型。 .proto
檔案中的 gRPC 呼叫會轉譯成可呼叫之具體類型的方法。 對於 greet.proto
(先前所述的範例),會產生具體的 GreeterClient
類型。 呼叫 GreeterClient.SayHelloAsync
以起始對伺服器的 gRPC 呼叫。
static async Task Main(string[] args)
{
// The port number(5001) must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
根據預設,系統會針對 <Protobuf>
項目群組中包含的每個 .proto
檔案產生伺服器和用戶端資產。 為了確保只會在伺服器專案中產生伺服器資產,GrpcServices
屬性會設定為 Server
。
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
同樣地,該屬性會在用戶端專案中設定為 Client
。