本文內容
本文檔概述在 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
。