使用 C# 的 gRPC 服務

本文件概述以 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

其他資源