ASP.NET Core 3.0使用gRPC的具體方法
一.簡(jiǎn)介
gRPC 是一個(gè)由Google開源的,跨語(yǔ)言的,高性能的遠(yuǎn)程過(guò)程調(diào)用(RPC)框架。 gRPC使客戶端和服務(wù)端應(yīng)用程序可以透明地進(jìn)行通信,并簡(jiǎn)化了連接系統(tǒng)的構(gòu)建。它使用HTTP/2作為通信協(xié)議,使用 Protocol Buffers 作為序列化協(xié)議。
它的主要優(yōu)點(diǎn):
- 現(xiàn)代高性能輕量級(jí) RPC 框架。
- 約定優(yōu)先的 API 開發(fā),默認(rèn)使用 Protocol Buffers 作為描述語(yǔ)言,允許與語(yǔ)言無(wú)關(guān)的實(shí)現(xiàn)。
- 可用于多種語(yǔ)言的工具,以生成強(qiáng)類型的服務(wù)器和客戶端。
- 支持客戶端,服務(wù)器雙向流調(diào)用。
- 通過(guò)Protocol Buffers二進(jìn)制序列化減少網(wǎng)絡(luò)使用。
- 使用 HTTP/2 進(jìn)行傳輸
這些優(yōu)點(diǎn)使gRPC非常適合:
- 高性能輕量級(jí)微服務(wù) - gRPC設(shè)計(jì)為低延遲和高吞吐量通信,非常適合需要高性能的輕量級(jí)微服務(wù)。
- 多語(yǔ)言混合開發(fā) - gRPC工具支持所有流行的開發(fā)語(yǔ)言,使gRPC成為多語(yǔ)言開發(fā)環(huán)境的理想選擇。
- 點(diǎn)對(duì)點(diǎn)實(shí)時(shí)通信 - gRPC對(duì)雙向流調(diào)用提供出色的支持。gRPC服務(wù)可以實(shí)時(shí)推送消息而無(wú)需輪詢。
- 網(wǎng)絡(luò)受限環(huán)境 - 使用 Protocol Buffers二進(jìn)制序列化消息,該序列化始終小于等效的JSON消息,對(duì)網(wǎng)絡(luò)帶寬需求比JSON小
不建議使用gRPC的場(chǎng)景:
- 瀏覽器可訪問(wèn)的API - 瀏覽器不完全支持gRPC。雖然gRPC-Web可以提供瀏覽器支持,但是它有局限性,引入了服務(wù)器代理
- 廣播實(shí)時(shí)通信 - gRPC支持通過(guò)流進(jìn)行實(shí)時(shí)通信,但不存在向已注冊(cè)連接廣播消息的概念
- 進(jìn)程間通信 - 進(jìn)程必須承載HTTP/2才能接受傳入的gRPC調(diào)用,對(duì)于Windows,進(jìn)程間通信管道是一種更快速的方法。
摘自微軟官方文檔
支持的語(yǔ)言如下:

二.gRPC on .NET Core
gRPC 現(xiàn)在可以非常簡(jiǎn)單的在 .NET Core 和 ASP.NET Core 中使用,在 .NET Core 上的實(shí)現(xiàn)的開源地址:https://github.com/grpc/grpc-dotnet ,它目前由微軟官方 ASP.NET 項(xiàng)目的人員進(jìn)行維護(hù),良好的接入 .NET Core 生態(tài)。
.NET Core 的 gRPC 功能如下:
- Grpc.AspNetCore 一個(gè)用于在ASP.NET Core承載gRPC服務(wù)的框架,將 gRPC和ASP.NET Core 功能集成在一起,如:日志、依賴注入、身份認(rèn)證和授權(quán)。
- Grpc.Net.Client 基于HttpClient (HttpClient現(xiàn)已支持HTTP/2)的 gRPC客戶端
- Grpc.Net.ClientFactory 與gRPC客戶端集成的
HttpClientFactory,允許對(duì)gRPC客戶端進(jìn)行集中配置,并使用DI注入到應(yīng)用程序中
三.使用 ASP.NET Core 創(chuàng)建 gRPC 服務(wù)
通過(guò) Visual Studio 2019 (16.3.0)提供的模板,可以快速創(chuàng)建 gRPC 服務(wù)。

來(lái)扒拉一下默認(rèn)源碼包含了什么東東。
① 配置文件 appsettings.json ,多了Kestrel 啟用 HTTP/2 的配置,因?yàn)?gRPC 是基于 HTTP/2 來(lái)通信的

② PB協(xié)議文件 greet.proto 用于自動(dòng)生成服務(wù)、客戶端和消息(表示傳遞的數(shù)據(jù))的C# Class

③ 服務(wù)類 GreeterService ,服務(wù)類集成的 Greeter.GreeterBase 來(lái)自于根據(jù)proto文件自動(dòng)生成的,生成的類在 obj\Debug\netcoreapp3.0目錄下

自動(dòng)生成的類:

④ Startup.cs類,將 gRPC服務(wù)添加到了終結(jié)點(diǎn)路由中

⑤ csproj 項(xiàng)目文件,包含了 proto 文件引用

2.運(yùn)行
第一次運(yùn)行會(huì)提示是否信任證書,點(diǎn)擊“是”


這是因?yàn)镠TTP/2需要HTTPS,盡管HTTP/2協(xié)議沒(méi)有明確規(guī)定需要HTTPS,但是為了安全在瀏覽器實(shí)現(xiàn)上都要求了HTTPS,所以現(xiàn)在的HTTP/2和HTTPS基本都是一對(duì)。

四. 創(chuàng)建 gRPC 客戶端
1.添加一個(gè).NET Core 控制臺(tái)應(yīng)用程序
2.通過(guò)nuget添加包:Grpc.Net.Client、Google.Protobuf、Grpc.Tools

3.將服務(wù)的 proto 文件復(fù)制到客戶端

4.編輯客戶端項(xiàng)目文件,添加關(guān)于proto文件的描述
<ItemGroup> <Protobuf Include="Protos\greet.proto" GrpcServices="Client" /> </ItemGroup>
注意 GrpcServices="Client" 這里是Client和服務(wù)是不一樣的
5.生成客戶端項(xiàng)目可以通過(guò)proto文件生成類
6.添加客戶端調(diào)用代碼
static async Task Main(string[] args)
{
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "曉晨" });
Console.WriteLine("Greeter 服務(wù)返回?cái)?shù)據(jù): " + reply.Message);
Console.ReadKey();
}
7.先啟動(dòng)服務(wù),然后運(yùn)行客戶端

這里可以看到,客戶端成功調(diào)用了服務(wù),收到了返回的消息。
五.自己動(dòng)手寫一個(gè)服務(wù)
前面我們使用的 Greeter 服務(wù)是由模板自動(dòng)給我們創(chuàng)建的,現(xiàn)在我們來(lái)自己動(dòng)手寫一個(gè)服務(wù)。
1.定義 proto 文件 LuCat.proto,并在csproj項(xiàng)目文件中添加描述
syntax = "proto3";
option csharp_namespace = "AspNetCoregRpcService";
import "google/protobuf/empty.proto";
package LuCat; //定義包名
//定義服務(wù)
service LuCat{
//定義吸貓方法
rpc SuckingCat(google.protobuf.Empty) returns(SuckingCatResult);
}
message SuckingCatResult{
string message=1;
}
2.實(shí)現(xiàn)服務(wù) LuCatService.cs
public class LuCatService:LuCat.LuCatBase
{
private static readonly List<string> Cats=new List<string>(){"英短銀漸層","英短金漸層","美短","藍(lán)貓","貍花貓","橘貓"};
private static readonly Random Rand=new Random(DateTime.Now.Millisecond);
public override Task<SuckingCatResult> SuckingCat(Empty request, ServerCallContext context)
{
return Task.FromResult(new SuckingCatResult()
{
Message = $"您吸了一只{Cats[Rand.Next(0, Cats.Count)]}"
});
}
}
3.在 Startup終結(jié)點(diǎn)路由中注冊(cè)
endpoints.MapGrpcService<LuCatService>();
4.添加客戶端調(diào)用
var catClient = new LuCat.LuCatClient(channel);
var catReply = await catClient.SuckingCatAsync(new Empty());
Console.WriteLine("調(diào)用擼貓服務(wù):"+ catReply.Message);
5.運(yùn)行測(cè)試

六.實(shí)際使用中的技巧
技巧1
上面章節(jié)的操作步驟中,我們需要在服務(wù)和客戶端之間復(fù)制proto,這是一個(gè)可以省略掉的步驟。
1.復(fù)制 Protos 文件夾到解決方案根目錄(sln文件所在目錄)

2.刪除客戶端和服務(wù)項(xiàng)目中的 Protos 文件夾
3.在客戶端項(xiàng)目文件csproj中添加關(guān)于proto文件的描述
<ItemGroup> <Protobuf Include="..\..\Protos\greet.proto" GrpcServices="Client" Link="Protos\greet.proto" /> </ItemGroup>
4.在服務(wù)項(xiàng)目文件csproj中添加關(guān)于proto文件的描述
<ItemGroup> <Protobuf Include="..\..\Protos\greet.proto" GrpcServices="Server" Link="Protos\greet.proto" /> </ItemGroup>
在實(shí)際項(xiàng)目中,請(qǐng)自己計(jì)算相對(duì)路徑
5.這樣兩個(gè)項(xiàng)目都是使用的一個(gè)proto文件,只用維護(hù)這一個(gè)文件即可

技巧2
我們?cè)趯?shí)際項(xiàng)目中使用,肯定有多個(gè) proto 文件,難道我們每添加一個(gè) proto 文件都要去更新 csproj文件?
我們可以使用MSBuild變量來(lái)幫我們完成,我們將 csproj 項(xiàng)目文件中引入proto文件信息進(jìn)行修改。
服務(wù)端:
<ItemGroup> <Protobuf Include="..\..\Protos\*.proto" GrpcServices="Server" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" /> </ItemGroup>
客戶端:
<ItemGroup> <Protobuf Include="..\..\Protos\*.proto" GrpcServices="Client" Link="Protos\%(RecursiveDir)%(Filename)%(Extension)" /> </ItemGroup>
示例:

七.總結(jié)
gRPC 現(xiàn)目前是一款非常成熟的高性能RPC框架,當(dāng)前的生態(tài)是非常好的,很多公司的產(chǎn)品或者開源項(xiàng)目都有在使用gRPC,有了它,相信可以讓我們更容易的構(gòu)建.NET Core 微服務(wù),可以讓 .NET Core 更好的接入 gRPC 生態(tài)。不得不說(shuō)這是 .NET Core 3.0 帶來(lái)的最令人振奮的特性之一。
參考資料:
在ASP.NET Core中創(chuàng)建gRPC客戶端和服務(wù)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 使用grpcui測(cè)試ASP.NET core的gRPC服務(wù)
- .NET?Core(.NET6)中g(shù)RPC使用實(shí)踐
- .Net?Core微服務(wù)rpc框架GRPC通信實(shí)際運(yùn)用
- .Net?Core微服務(wù)rpc框架GRPC通信基礎(chǔ)
- 在?ASP.NET?Core?中為?gRPC?服務(wù)添加全局異常處理
- 如何在.NET Core中為gRPC服務(wù)設(shè)計(jì)消息文件(Proto)
- .Net Core中使用Grpc的方法
- ASP.NET Core 3.0 gRPC攔截器的使用
- 圖析ASP.NET Core引入gRPC服務(wù)模板
- ASP.NET Core中Grpc通信的簡(jiǎn)單用法
相關(guān)文章
利用VS2019創(chuàng)建Web項(xiàng)目并發(fā)送到IIS及IIS與ASP.NET配置教程
這篇文章主要介紹了利用VS2019創(chuàng)建Web項(xiàng)目,并發(fā)送到IIS,以及IIS與ASP.NET配置,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03
ASP.NET中XML轉(zhuǎn)JSON的方法實(shí)例
這篇文章主要介紹了ASP.NET中XML轉(zhuǎn)JSON的方法,實(shí)例講述了XML轉(zhuǎn)json的原理與實(shí)現(xiàn)過(guò)程,具有一定的實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10
asp.net core webapi文件上傳功能的實(shí)現(xiàn)
這篇文章主要介紹了asp.net core webapi文件上傳功能的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
ASP.NET 固定標(biāo)題列與欄位的具體實(shí)現(xiàn)
客戶提這個(gè)要求很久了,最近才時(shí)間弄,但是看到百度中要沒(méi)有很多詳細(xì)的代碼。廢話不多說(shuō)直接貼代碼。2013-06-06
asp.net數(shù)據(jù)綁定DataBind使用方法
asp.net數(shù)據(jù)綁定DataBind使用方法,大家參考使用吧2013-12-12
ASP.NET MVC使用RazorEngine解析模板生成靜態(tài)頁(yè)
這篇文章主要介紹了ASP.NET MVC使用RazorEngine解析模板生成靜態(tài)頁(yè)的相關(guān)資料,需要的朋友可以參考下2016-05-05
asp.net 購(gòu)物車的實(shí)現(xiàn)淺析
我從來(lái)沒(méi)有進(jìn)行過(guò)正式的web開發(fā),但是我一直喜歡web,所以這篇文章也是我轉(zhuǎn)行web的一個(gè)開始吧。或多或少我也參考了幾個(gè)網(wǎng)站的實(shí)現(xiàn)(當(dāng)然了,只是看看大概的功能而已),所以也請(qǐng)大家多多指教。2011-02-02

