早就聽說ASP.NET Core 3.0中引入了gRPC的服務模闆,正好趁着家裡電腦剛做了新系統,然後裝了VS2019的功夫來體驗一把。同時記錄體驗的過程。如果你也想按照本文的步驟體驗的話,那你得先安裝.NET Core3.0預覽版的SDK。至于開發工具我用的時VS2019,當然你也可以使用VS Code進行。
作者:依樂祝
原文位址:https://www.cnblogs.com/yilezhu/p/10631420.html
gRPC的簡單介紹
gRPC 是一種與語言無關的高性能遠端過程調用 (RPC) 架構。 有關 gRPC 基礎知識的詳細資訊,請參閱 gRPC 文檔頁。
gRPC 的主要優點是:
- 現代高性能輕量級 RPC 架構。
- 協定優先 API 開發,預設使用協定緩沖區,允許與語言無關的實作。
- 可用于多種語言的工具,以生成強類型伺服器和用戶端。
- 支援用戶端、伺服器和雙向流式處理調用。
- 使用 Protobuf 二進制序列化減少對網絡的使用。
這些優點使 gRPC 适用于:
- 效率至關重要的輕量級微服務。
- 需要多種語言用于開發的 Polyglot 系統。
- 需要處理流式處理請求或響應的點對點實時服務。
ASP.NET Core 3.0上gRPC服務模闆初體驗
建立gRPC服務
- 打開VS2019 從 Visual Studio“檔案”菜單中選擇“建立” > “項目”。(由于我是新打開的VS,是以按照如下圖所示建立新項目)
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 如下圖所示,選擇建立《ASP.NET Core Web 應用程式》,然後點選下一步
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 在此頁面按照下圖所示,輸入項目名稱,位置,解決方案名稱,然後點選右下角的“建立”按鈕進行建立。
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 你以為上述步驟中點選“建立”就結束了嘛?說好的要建立gRPC服務模闆的,是以,點選上面的建立後會彈出如下圖所示,讓你選擇服務模闆的視窗,這裡按照下圖所示選擇gRPC服務模闆,然後再次點選右下角的建立,才是真正的建立項目。
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 建立成功後,會出現如下圖所示的項目結構
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 至此,我們就建立好了一個gRPC服務的模闆,接下來我們先測試一番,然後再好好的看下這個模闆的結構吧
測試gRPC服務
- 首先打開
這個服務端的工作目錄,然後HelloGrpc.Server
彈出如下圖所示的右鍵菜單,如圖所示打開ps視窗Shift+滑鼠右鍵
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 輸入
指令運作此gRPC服務端項目,如下圖所示,說明服務端啟動正常,并開始監聽對應的端口。dotnet run
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 同樣的方法,我們啟動用戶端,這時候用戶端會向該服務端發送一條包含具有其名稱“GreeterClient”的消息的問候資訊。 該服務端将發送一條消息“Hello GreeterClient”作為響應,并顯示在指令提示符中。如下圖所示:
ASP.NET Core 3.0 上的gRPC服務模闆初體驗(多圖) - 至此,gRPC服務模闆建立的服務端以及用戶端測試成功。下面我們就好好的探究一下這個服務模闆吧。
gRPC模闆解析
在
HelloGrpc.Server
服務的端項目中有如下幾個檔案
- greet.proto:greet.proto 檔案定義
gRPC,且用于生成 gRPC 伺服器資産。Greeter
- Services 檔案夾:包含
服務的實作。Greeter
- appSettings.json:包含配置資料,如 Kestrel 使用的協定。(熟悉ASP.NET Core的你一定很熟悉)
- Program.cs:包含 gRPC 服務的入口點。(熟悉ASP.NET Core的你一定很熟悉)
- Startup.cs:
的啟動配置檔案,包含配置應用行為的代碼。(熟悉ASP.NET Core的你一定很熟悉)IWebHostBuilder
gRPC 用戶端
HelloGrpc.Client
檔案:
Program.cs 包含 gRPC 用戶端的入口點和邏輯。
下面我們再打開每個檔案看看裡面究竟是什麼東東吧。
proto檔案
proto
GRPC使用約定優先的API開發方法。預設情況下,使用協定緩沖區(Protobuf)作為接口設計語言(IDL)。這個
.proto
檔案包含:
- GRPC服務的定義。
- 在用戶端和伺服器之間發送的消息。
有關Protobuf檔案文法的更多資訊,請參見正式檔案(原型).
如我們模闆中建立的
greet.proto
檔案内容如下:
syntax = "proto3";
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;
}
- 定義
服務。Greeter
- 這個
服務定義Greeter
請求。SayHello
-
發送SayHello
消息并接收HelloRequest
HelloResponse
資訊:
那麼你可能要問了,這個.proto檔案是如何包含在項目中的呢,其實,如果你打開.csproject檔案就會看到,通過将該檔案添加到
的ItemGroup中即可,如下所示:<Protobuf>
<ItemGroup>
<Protobuf Include="..\Protos\*.proto" GrpcServices="Server" />
<Content Include="@(Protobuf)" LinkBase="" />
</ItemGroup>
C#對.proto檔案的工具支援
工具包Grpc.Tools 被用來從.proto檔案生成C#檔案。生成的資産(檔案)具有如下特性:
- 每次建構項目時都會根據需要進行生成。
- 生成的檔案不會被添加到項目或簽入源代碼管理。
- 生成的C#檔案是包含在OBJ目錄。
伺服器和用戶端項目都需要此包。
Grpc.Tools
可以通過在VisualStudio中使用包管理器或添加
<PackageReference>
到項目檔案:
XML複制
<PackageReference Include="Grpc.Tools" Version="1.19.0-pre1" PrivateAssets="All" />
工具包在運作時并不是必需的,是以,應該用
PrivateAssets="All"
.
Services 檔案夾中的具體的gRPC服務
我們知道
Grpc.Tools
工具包将根據.proto檔案的定義翻譯并生成對應的C#類型的檔案。
對于伺服器端資産,将生成一個抽象的服務基類型。基類型包含在.proto檔案中包含的所有GRPC調用的定義。然後,您将建立從此基類型派生的具體服務實作,并實作GRPC調用的邏輯。對于前面描述的
greet.proto
示例,将生成包含虛拟
SayHello
方法的抽象
GreeterBase
類型。具體的實作
GreeterService
重寫該方法并實作處理GRPC調用的邏輯。
正如
HelloGrpc.Server
項目中的
Services\GreeterService.cs
中的代碼
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply>
SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
對于用戶端,将生成一個具體的用戶端類型中的GRPC調用。.proto檔案被轉換為可以調用的具體類型上的方法。為
greet.proto
前面描述的示例,一個具體的
GreeterClient
類型生成。這個
GreeterClient
類型包含
SayHello
方法,可以調用該方法來啟動對伺服器的GRPC調用。
public class Program
{
static async Task Main(string[] args)
{
// Include port of the gRPC server as an application argument
var port = args.Length > 0 ? args[0] : "50051";
var channel = new Channel("localhost:" + port, ChannelCredentials.Insecure);
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
await channel.ShutdownAsync();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
預設情況下,分别生成伺服器和用戶端資産。.proto檔案包含在
<Protobuf>
項目組。若要確定僅在伺服器項目中生成伺服器資産,
GrpcServices
屬性設定為
Server
<ItemGroup>
<Protobuf Include="..\Protos\*.proto" GrpcServices="Server" />
<Content Include="@(Protobuf)" LinkBase="" />
</ItemGroup>
類似地,屬性設定為
Client
在僅在客戶項目中生成。
Startup
Startup
中我們發現跟普通的ASP.NET Core程式有所不同,具體的如下圖所示:在
ConfigureServices
服務中引入了gRPC服務,然後在
Configure
加入了路由
而這裡需要引入三個與gRPC相關的nuget包
- Grpc.AspNetCore.Server
- Google.Protobuf對于Protobuf消息API。
- Grpc.Tools
這裡需要說明的是
ASP.NET Core 中間件和功能共享路由管道,是以可以将應用程式配置為服務其他請求處理程式。其他請求處理程式(如MVC控制器)可以與配置的GRPC服務路由并行工作。
其他需要說明的内容
與ASP.NET Core 接口的內建
GRPC服務可以完全通路ASP.NETCore功能,如依賴注入(Di)和日志功能。例如,服務實作可以通過構造函數解析DI容器中的記錄器服務:
public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}
預設情況下,GRPC服務可以解析具有任意生存期的其他DI服務(Singleton, Scoped, or Transient)。
在GRPC方法中解析HttpContext
GRPC 應用程式接口提供對某些HTTP/2消息資料的通路,例如method, host, header, and trailers。通路是通過
ServerCallContext
參數傳遞給每個GRPC方法:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply>
SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
ServerCallContext
不提供對所有ASP.NET 接口中
HttpContext
的完全通路。
GetHttpContext
擴充方法提供對表示ASP.NET API中底層HTTP/2消息的httpContext的完全通路:
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request,
ServerCallContext context)
{
var httpContext = context.GetHttpContext();
return Task.FromResult(new HelloReply
{
Message = "Using https: " + httpContext.Request.IsHttps
});
}
}
請求體資料速率限制
預設情況下,Kestrel伺服器設定為最小請求主體資料速率。對于用戶端流式和雙工流式的請求,此速率可能不滿足,并且連接配接可能逾時。當GRPC服務包括用戶端流和雙工流調用時,必須禁用最小請求正文資料速率限制:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel((context, options) =>
{
options.Limits.MinRequestBodyDataRate = null;
});
});
}
參考文章
- gRPC services with C#
- Tutorial: Get started with gRPC in ASP.NET Core
- gRPC services with ASP.NET Core
- Migrating gRPC services from C-core to ASP.NET Core
總結
今天分享的内容有點多,目的就是使記錄盡可能的詳細,盡可能用通俗易懂的語言來進行描述,讓大家能用起來。在asp.net core3.0中把grpc服務作為第一等公民進行支援,是以我們有必要進行下了解。可能很多朋友會有疑問了,我Web API用的爽歪歪,幹嘛還要用gRPC這種遠端過程調用協定啊。關于這個問題,我準備再單獨開一篇文章進行講解,最後感謝大家的閱讀,碼字不易,多多推薦支援吧!
作者:依樂祝(祝雷)
出處:https://www.cnblogs.com/yilezhu
聯系:[email protected] .NET Core實戰項目交流群:637326624 微信:jkingzhu
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。如有問題或建議,請多多賜教,非常感謝。