使用 C# 的 gRPC 服務

本文內容

  1. proto 文件
  2. 將 .proto 文件添加到 C# 應用
  3. 對 .proto 文件的 C# 工具支持
  4. 生成的 C# 資產
  5. 其他資源

本文檔概述在 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 中的包管理器或通過將 <PackageReference> 添加到項目文件來添加 Grpc.AspNetCore

<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# 資產

工具包會生成表示在所包含 .proto 文件中定義的消息的 C# 類型。

對於服務器端資產,會生成抽象服務基類型。 基類型包含 .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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章