圖析ASP.NET Core引入gRPC服務模板
早就聽說ASP.NET Core 3.0中引入了gRPC的服務模板,正好趁著家里電腦剛做了新系統(tǒng),然后裝了VS2019的功夫來體驗一把。同時記錄體驗的過程。如果你也想按照本文的步驟體驗的話,那你得先安裝.NET Core3.0預覽版的SDK。至于開發(fā)工具我用的時VS2019,當然你也可以使用VS Code進行。
gRPC的簡單介紹
gRPC 是一種與語言無關的高性能遠程過程調(diào)用 (RPC) 框架。 有關 gRPC 基礎知識的詳細信息,請參閱 gRPC 文檔頁。
gRPC 的主要優(yōu)點是:
- 現(xiàn)代高性能輕量級 RPC 框架。
- 協(xié)定優(yōu)先 API 開發(fā),默認使用協(xié)議緩沖區(qū),允許與語言無關的實現(xiàn)。
- 可用于多種語言的工具,以生成強類型服務器和客戶端。
- 支持客戶端、服務器和雙向流式處理調(diào)用。
- 使用 Protobuf 二進制序列化減少對網(wǎng)絡的使用。
這些優(yōu)點使 gRPC 適用于:
- 效率至關重要的輕量級微服務。
- 需要多種語言用于開發(fā)的 Polyglot 系統(tǒng)。
- 需要處理流式處理請求或響應的點對點實時服務。
ASP.NET Core 3.0上gRPC服務模板初體驗
創(chuàng)建gRPC服務
1 .打開VS2019 從 Visual Studio“文件”菜單中選擇“新建” > “項目”。(由于我是新打開的VS,所以按照如下圖所示創(chuàng)建新項目)
2.如下圖所示,選擇創(chuàng)建《ASP.NET Core Web 應用程序》,然后點擊下一
3.在此頁面按照下圖所示,輸入項目名稱,位置,解決方案名稱,然后點擊右下角的“創(chuàng)建”按鈕進行創(chuàng)建。
4.你以為上述步驟中點擊“創(chuàng)建”就結(jié)束了嘛?說好的要創(chuàng)建gRPC服務模板的,所以,點擊上面的創(chuàng)建后會彈出如下圖所示,讓你選擇服務模板的窗口,這里按照下圖所示選擇gRPC服務模板,然后再次點擊右下角的創(chuàng)建,才是真正的創(chuàng)建項目。
5.創(chuàng)建成功后,會出現(xiàn)如下圖所示的項目結(jié)構
6.至此,我們就創(chuàng)建好了一個gRPC服務的模板,接下來我們先測試一番,然后再好好的看下這個模板的結(jié)構吧
測試gRPC服務
1.首先打開HelloGrpc.Server
這個服務端的工作目錄,然后Shift+鼠標右鍵
彈出如下圖所示的右鍵菜單,如圖所示打開ps窗口
2.輸入dotnet run
命令運行此gRPC服務端項目,如下圖所示,說明服務端啟動正常,并開始監(jiān)聽對應的端口。
3.同樣的方法,我們啟動客戶端,這時候客戶端會向該服務端發(fā)送一條包含具有其名稱“GreeterClient”的消息的問候信息。 該服務端將發(fā)送一條消息“Hello GreeterClient”作為響應,并顯示在命令提示符中。如下圖所示:
4.至此,gRPC服務模板創(chuàng)建的服務端以及客戶端測試成功。下面我們就好好的探究一下這個服務模板吧。
gRPC模板解析
在HelloGrpc.Server
服務的端項目中有如下幾個文件
- greet.proto:greet.proto 文件定義
Greeter
gRPC,且用于生成 gRPC 服務器資產(chǎn)。 - Services 文件夾:包含
Greeter
服務的實現(xiàn)。 - appSettings.json:包含配置數(shù)據(jù),如 Kestrel 使用的協(xié)議。(熟悉ASP.NET Core的你一定很熟悉)
- Program.cs:包含 gRPC 服務的入口點。(熟悉ASP.NET Core的你一定很熟悉)
- Startup.cs:
IWebHostBuilder
的啟動配置文件,包含配置應用行為的代碼。(熟悉ASP.NET Core的你一定很熟悉)
gRPC 客戶端 HelloGrpc.Client
文件:
Program.cs 包含 gRPC 客戶端的入口點和邏輯。
下面我們再打開每個文件看看里面究竟是什么東東吧。
proto文件
proto
GRPC使用約定優(yōu)先的API開發(fā)方法。默認情況下,使用協(xié)議緩沖區(qū)(Protobuf)作為接口設計語言(IDL)。這個.proto
文件包含:
- GRPC服務的定義。
- 在客戶端和服務器之間發(fā)送的消息。
有關Protobuf文件語法的更多信息,請參見正式文件(原型).
如我們模板中創(chuàng)建的greet.proto
文件內(nèi)容如下:
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
發(fā)送HelloRequest
消息并接收HelloResponse
信息:- 那么你可能要問了,這個.proto文件是如何包含在項目中的呢,其實,如果你打開.csproject文件就會看到,通過將該文件添加到
<Protobuf>
的ItemGroup中即可,如下所示:
<ItemGroup> <Protobuf Include="..\Protos\*.proto" GrpcServices="Server" /> <Content Include="@(Protobuf)" LinkBase="" /> </ItemGroup>
C#對.proto文件的工具支持
工具包Grpc.Tools 被用來從.proto文件生成C#文件。生成的資產(chǎn)(文件)具有如下特性:
- 每次構建項目時都會根據(jù)需要進行生成。
- 生成的文件不會被添加到項目或簽入源代碼管理。
- 生成的C#文件是包含在OBJ目錄。
服務器和客戶端項目都需要此包。Grpc.Tools
可以通過在VisualStudio中使用包管理器或添加<PackageReference>
到項目文件:
XML復制
<PackageReference Include="Grpc.Tools" Version="1.19.0-pre1" PrivateAssets="All" />
工具包在運行時并不是必需的,因此,應該用PrivateAssets="All"
.
Services 文件夾中的具體的gRPC服務
我們知道Grpc.Tools
工具包將根據(jù).proto文件的定義翻譯并生成對應的C#類型的文件。
對于服務器端資產(chǎn),將生成一個抽象的服務基類型?;愋桶?em>.proto文件中包含的所有GRPC調(diào)用的定義。然后,您將創(chuàng)建從此基類型派生的具體服務實現(xiàn),并實現(xiàn)GRPC調(diào)用的邏輯。對于前面描述的greet.proto
示例,將生成包含虛擬SayHello
方法的抽象GreeterBase
類型。具體的實現(xiàn)GreeterService
重寫該方法并實現(xiàn)處理GRPC調(diào)用的邏輯。
正如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調(diào)用。.proto文件被轉(zhuǎn)換為可以調(diào)用的具體類型上的方法。為greet.proto
前面描述的示例,一個具體的GreeterClient
類型生成。這個GreeterClient
類型包含SayHello
方法,可以調(diào)用該方法來啟動對服務器的GRPC調(diào)用。
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(); } }
默認情況下,分別生成服務器和客戶端資產(chǎn)。.proto文件包含在<Protobuf>
項目組。若要確保僅在服務器項目中生成服務器資產(chǎn),GrpcServices
屬性設置為Server
.
XML復制
<ItemGroup> <Protobuf Include="..\Protos\*.proto" GrpcServices="Server" /> <Content Include="@(Protobuf)" LinkBase="" /> </ItemGroup>
類似地,屬性設置為Client
在僅在客戶項目中生成。
Startup
在Startup
中我們發(fā)現(xiàn)跟普通的ASP.NET Core程序有所不同,具體的如下圖所示:在ConfigureServices
服務中引入了gRPC服務,然后在Configure
加入了路由
而這里需要引入三個與gRPC相關的nuget包
- Grpc.AspNetCore.Server
- Google.Protobuf對于Protobuf消息API。
- Grpc.Tools
這里需要說明的是
ASP.NET Core 中間件和功能共享路由管道,因此可以將應用程序配置為服務其他請求處理程序。其他請求處理程序(如MVC控制器)可以與配置的GRPC服務路由并行工作。
其他需要說明的內(nèi)容
與ASP.NET Core 接口的集成
GRPC服務可以完全訪問ASP.NETCore功能,如依賴注入(Di)和日志功能。例如,服務實現(xiàn)可以通過構造函數(shù)解析DI容器中的記錄器服務:
public class GreeterService : Greeter.GreeterBase { public GreeterService(ILogger<GreeterService> logger) { } }
默認情況下,GRPC服務可以解析具有任意生存期的其他DI服務(Singleton, Scoped, or Transient)。
在GRPC方法中解析HttpContext
GRPC 應用程序接口提供對某些HTTP/2消息數(shù)據(jù)的訪問,例如method, host, header, and trailers。訪問是通過ServerCallContext
參數(shù)傳遞給每個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 }); } }
請求體數(shù)據(jù)速率限制
默認情況下,Kestrel服務器設置為最小請求主體數(shù)據(jù)速率。對于客戶端流式和雙工流式的請求,此速率可能不滿足,并且連接可能超時。當GRPC服務包括客戶端流和雙工流調(diào)用時,必須禁用最小請求正文數(shù)據(jù)速率限制:
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; }); }); }
參考文章
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
總結(jié)
今天分享的內(nèi)容有點多,目的就是使記錄盡可能的詳細,盡可能用通俗易懂的語言來進行描述,讓大家能用起來。在asp.net core3.0中把grpc服務作為第一等公民進行支持,所以我們有必要進行下了解??赡芎芏嗯笥褧幸蓡柫耍襑eb API用的爽歪歪,干嘛還要用gRPC這種遠程過程調(diào)用協(xié)議啊。關于這個問題,我準備再單獨開一篇文章進行講解,最后感謝大家的閱讀,碼字不易,多多推薦支持吧!
相關文章
Entity?Framework?Core生成數(shù)據(jù)庫表
這篇文章介紹了Entity?Framework?Core生成數(shù)據(jù)庫表的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-03-03Global.asax的Application_Error實現(xiàn)錯誤記錄/錯誤日志的代碼
本文為大家介紹下利用Global.asax的Application_Error實現(xiàn)錯誤記錄,具體如下,有此需求的朋友可以參考下,希望對大家有所幫助2013-08-08Asp.Net Couchbase Memcached圖文安裝調(diào)用開發(fā)
本文主要是是如何安裝CouchBase服務端,以及客戶端如何進行調(diào)用。圖文詳解,大家參考吧2013-11-11asp.net AjaxControlToolKit--TabContainer控件的介紹
ModalPopup控件允許一個asp頁面的部分內(nèi)容以對話框的模式顯示給用戶,同時會限制用戶于頁面的其他部分交互。對話框顯示的內(nèi)容可以是一個層級,這個層級的背景可以使用戶自定義的格式,簡單的理解好比是一個對話框彈出來后,主頁面會顯示灰色,且不可操作。2009-06-06詳解ASP.NET MVC 解析模板生成靜態(tài)頁(RazorEngine)
我們在很多項目開發(fā)中會常常用到頁面靜態(tài)化,本篇文章主要介紹了詳解ASP.NET MVC 解析模板生成靜態(tài)頁(RazorEngine) ,具有一定的參考價值,有興趣的可以了解一下。2017-03-03