使用 C gRPC 服務#gRPC services with C#

本檔概述以 c # 撰寫 gRPC 應用程式所需的概念。This document outlines the concepts needed to write gRPC apps in C#. 本文所涵蓋的主題適用于以 C 核心為基礎和 ASP.NET Core 為基礎的 gRPC 應用程式。The topics covered here apply to both C-core-based and ASP.NET Core-based gRPC apps.

警告

Azure App Service 或 IIS 上目前不支援ASP.NET Core gRPCASP.NET Core gRPC is not currently supported on Azure App Service or IIS. Http.Sys 的 HTTP/2 執行不支援 gRPC 所依賴的 HTTP 回應尾端標頭。The HTTP/2 implementation of Http.Sys does not support HTTP response trailing headers which gRPC relies on. 如需詳細資訊,請參閱 此 GitHub 問題For more information, see this GitHub issue.

proto 檔案proto file

gRPC 使用合約優先的方法來開發 API。gRPC uses a contract-first approach to API development. 根據預設, (protobuf) 的通訊協定緩衝區作為介面定義語言 (IDL) 。Protocol buffers (protobuf) are used as the Interface Definition Language (IDL) by default. * Proto 檔案包含:The *.proto file contains:

  • GRPC 服務的定義。The definition of the gRPC service.
  • 用戶端與伺服器之間傳送的訊息。The messages sent between clients and servers.

如需 protobuf 檔語法的詳細資訊,請參閱 建立 .NET 應用程式的 Protobuf 訊息For more information on the syntax of protobuf files, see 建立 .NET 應用程式的 Protobuf 訊息.

例如,請考慮開始 使用 gRPC service中所使用的 歡迎 檔:For example, consider the greet.proto file used in Get started with gRPC service:

  • 定義 Greeter 服務。Defines a Greeter service.
  • Greeter服務會定義 SayHello 呼叫。The Greeter service defines a SayHello call.
  • SayHello 傳送 HelloRequest 訊息並接收 HelloReply 訊息:SayHello sends a HelloRequest message and receives a HelloReply message:
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 討論問題中讓我們知道。If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

將 proto 檔案新增至 C # 應用程式Add a .proto file to a C# app

藉由將 * proto 檔案新增至專案群組,即可將該檔案包含在專案中 <Protobuf>The *.proto file is included in a project by adding it to the <Protobuf> item group:

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>

根據預設, <Protobuf> 參考會產生實體用戶端和服務基類。By default, a <Protobuf> reference generates a concrete client and a service base class. 參考專案的 GrpcServices 屬性可以用來限制產生 c # 資產。The reference element's GrpcServices attribute can be used to limit C# asset generation. 有效 GrpcServices 的選項包括:Valid GrpcServices options are:

  • Both 不存在時 (預設值) Both (default when not present)
  • Server
  • Client
  • None

適用于 proto 檔案的 c # 工具支援C# Tooling support for .proto files

需要工具套件 Grpc ,才能從 * Proto 檔案產生 c # 資產。The tooling package Grpc.Tools is required to generate the C# assets from *.proto files. 產生的資產 (檔) :The generated assets (files):

  • 每次建立專案時,會根據需要來產生。Are generated on an as-needed basis each time the project is built.
  • 不會加入至專案或簽入原始檔控制。Aren't added to the project or checked into source control.
  • 是包含在 obj 目錄中的組建成品。Are a build artifact contained in the obj directory.

伺服器和用戶端專案都需要此封裝。This package is required by both the server and client projects. Grpc.AspNetCore中繼套件包含的參考 Grpc.ToolsThe Grpc.AspNetCore metapackage includes a reference to Grpc.Tools. 您可以 Grpc.AspNetCore 使用 Visual Studio 中的封裝管理員,或將加入至專案檔,以新增伺服器專案 <PackageReference>Server projects can add Grpc.AspNetCore using the Package Manager in Visual Studio or by adding a <PackageReference> to the project file:

<PackageReference Include="Grpc.AspNetCore" Version="2.28.0" />

用戶端專案應該直接參考 Grpc.Tools 使用 gRPC 用戶端所需的其他套件。Client projects should directly reference Grpc.Tools alongside the other packages required to use the gRPC client. 在執行時間不需要工具套件,因此相依性會標示為 PrivateAssets="All"The tooling package isn't required at runtime, so the dependency is marked with PrivateAssets="All":

<PackageReference Include="Google.Protobuf" Version="3.11.4" />
<PackageReference Include="Grpc.Net.Client" Version="2.28.0" />
<PackageReference Include="Grpc.Tools" Version="2.28.1">

產生的 c # 資產Generated C# assets

工具套件會產生 c # 類型,代表包含的 * proto 檔案中定義的訊息。The tooling package generates the C# types representing the messages defined in the included *.proto files.

針對伺服器端資產,會產生抽象服務基底類型。For server-side assets, an abstract service base type is generated. 基底類型包含 gRPC 中包含的所有呼叫的定義 The base type contains the definitions of all the gRPC calls contained in the .proto file. 建立衍生自此基底類型的具體服務執行,並執行 gRPC 呼叫的邏輯。Create a concrete service implementation that derives from this base type and implements the logic for the gRPC calls. greet.proto 先前所述的範例, GreeterBase 會產生包含虛擬方法的抽象型別 SayHelloFor the greet.proto, the example described previously, an abstract GreeterBase type that contains a virtual SayHello method is generated. 具體的實作為會 GreeterService 覆寫方法,並執行處理 gRPC 呼叫的邏輯。A concrete implementation GreeterService overrides the method and implements the logic handling the gRPC call.

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
        });
    }
}

若為用戶端資產,則會產生具體的用戶端類型。For client-side assets, a concrete client type is generated. proto 檔中的 gRPC 呼叫會轉譯成具象型別上的方法,可以呼叫。The gRPC calls in the .proto file are translated into methods on the concrete type, which can be called. 針對 greet.proto ,先前所述的範例 GreeterClient 會產生實體型別。For the greet.proto, the example described previously, a concrete GreeterClient type is generated. 呼叫 GreeterClient.SayHelloAsync 以初始化對伺服器的 gRPC 呼叫。Call GreeterClient.SayHelloAsync to initiate a gRPC call to the server.

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();
}

依預設,會針對專案群組中包含的每個 * proto 檔案產生伺服器和用戶端資產 <Protobuf>By default, server and client assets are generated for each *.proto file included in the <Protobuf> item group. 為確保伺服器專案中只會產生伺服器資產, GrpcServices 屬性會設定為 ServerTo ensure only the server assets are generated in a server project, the GrpcServices attribute is set to Server.

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>

同樣地,在 Client 用戶端專案中,屬性會設定為。Similarly, the attribute is set to Client in client projects.

其他資源Additional resources