一、gRPC簡介:
gRPC 是一個由Google開源的,跨語言的,高效能的遠端過程呼叫(RPC)框架。 gRPC使客戶端和服務端應用程式可以透明地進行通訊,並簡化了連線系統的構建。它使用HTTP/2作為通訊協議,使用 Protocol Buffers(協議緩衝區) 作為序列化協議。
引用自微軟文件:
gRPC 的主要優點是:
- 現代高效能輕量級 RPC 框架。
- 協定優先 API 開發,預設使用協議緩衝區,允許與語言無關的實現。
- 可用於多種語言的工具,以生成強型別伺服器和客戶端。
- 支援客戶端、伺服器和雙向流式處理呼叫。
- 使用 Protobuf 二進位制序列化減少對網路的使用。
這些優點使 gRPC 適用於:
- 效率至關重要的輕量級微服務。
- 需要多種語言用於開發的 Polyglot 系統。
- 需要處理流式處理請求或響應的點對點實時服務。
官方支援的gRPC語言,平臺和作業系統版本
Language | OS | Compilers / SDK |
---|---|---|
C/C++ | Linux, Mac | GCC 4.9+, Clang 3.4+ |
C/C++ | Windows 7+ | Visual Studio 2015+ |
C# | Linux, Mac | .NET Core, Mono 4+ |
C# | Windows 7+ | .NET Core, NET 4.5+ |
Dart | Windows, Linux, Mac | Dart 2.2+ |
Go | Windows, Linux, Mac | Go 1.13+ |
Java | Windows, Linux, Mac | JDK 8 recommended (Jelly Bean+ for Android) |
Kotlin/JVM | Windows, Linux, Mac | Kotlin 1.3+ |
Node.js | Windows, Linux, Mac | Node v8+ |
Objective-C | macOS 10.10+, iOS 9.0+ | Xcode 7.2+ |
PHP | Linux, Mac | PHP 7.0+ |
Python | Windows, Linux, Mac | Python 3.5+ |
Ruby | Windows, Linux, Mac | Ruby 2.3+ |
二、ASP.NET 中gRPC應用:
1、建立gRPC服務專案:新建專案
2、建立專案程式碼解析:
如圖可以看到建立目錄中:主要新增:greet.proto、GreeterService
a)greet.proto檔案說明:
//指定協議緩衝區使用版本 syntax = "proto3"; //定義C#實現的名稱空間 option csharp_namespace = "GrpcServiceDemo";
//定義包名 package greet; // 定義gRPC服務 service Greeter { //服務定義方法: 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; }
b)gRPC服務實現:服務類 GreeterService
,服務類整合的 Greeter.GreeterBase
來自於根據proto檔案自動生成的,生成的類在 obj\Debug\netcoreapp3.1
目錄下
//Greeter.GreeterBase由grpc.tools根據proto檔案自動生成。 //檔案路徑在:obj\debug\netcoreapp3.1 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 }); } }
c)Startup檔案主要包括:
public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { //注入Grpc服務
services.AddGrpc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => { //繫結服務實現介面 endpoints.MapGrpcService<GreeterService>(); //繫結預設節點輸出內容 endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); }); }); } }
d)專案檔案中新增了:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
e)配置檔案改變:指定以http2協議執行
"Kestrel": { "EndpointDefaults": { "Protocols": "Http2" } }
3、建立自己的gRCP服務介面:在建立WebApi專案時預設建立了個天氣預報介面,那麼就來實現一個獲取天氣預報的gRPC服務
a) 新增 weatherforecast.proto 檔案,定義服務介面
syntax = "proto3"; //匯入日期型別 import "google/protobuf/timestamp.proto"; //匯入空型別 import "google/protobuf/empty.proto"; //名稱空間 option csharp_namespace = "GrpcServiceDemo"; //包名稱 package weather; //天氣服務 service Weather { //指定城市天氣 rpc GetWeather (WeatherReques) returns (WeatherForecastInfo); //所有城市列表:入參為空 rpc GetWeatherList (google.protobuf.Empty) returns (WeatherList); } //請求具體城市名稱 message WeatherReques { string name = 1; } //返回天氣資料列表 message WeatherList{ repeated WeatherForecastInfo ListData =1; } //定義返回天氣資料型別 message WeatherForecastInfo { //日期時間型別 google.protobuf.Timestamp Date = 1; int32 TemperatureC = 2; int32 TemperatureF = 3; string Summary = 4; }
b) 實現天氣獲取介面
public class WeatherService : Weather.WeatherBase { private static readonly string[] Summaries = new[] {"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"}; private readonly ILogger<WeatherService> _logger; public WeatherService(ILogger<WeatherService> logger) { _logger = logger; } public override Task<WeatherForecastInfo> GetWeather(WeatherReques request, ServerCallContext context) { var rng = new Random(); var result = new WeatherForecastInfo { //時間轉換 Date = Timestamp.FromDateTimeOffset(new DateTimeOffset(DateTime.Now.AddDays(1))), TemperatureC = rng.Next(-20, 55), Summary = $"{Summaries[rng.Next(Summaries.Length)]}" }; return Task.FromResult(result); } public override Task<WeatherList> GetWeatherList(Empty request, ServerCallContext context) { var rng = new Random(); var data = Enumerable.Range(1, 5).Select(index => new WeatherForecastInfo { //時間轉換 Date = Timestamp.FromDateTimeOffset(new DateTimeOffset(DateTime.Now.AddDays(1))), TemperatureC = rng.Next(-20, 55), Summary = $"{ Summaries[rng.Next(Summaries.Length)]}" }); WeatherList weatherList = new WeatherList(); weatherList.ListData.Add(data); return Task.FromResult(weatherList); } }
c)在 Startup
終結點路由中註冊
endpoints.MapGrpcService<WeatherService>();
d)執行gRPC服務:
三、客戶端呼叫gRPC服務
1、建立.net core控制檯應用;並新增nuget包引用
Install-Package Grpc.Net.Client Install-Package Google.Protobuf Install-Package Grpc.Tools
2、將服務端中Protos檔案,拷貝到客戶端中,並在專案檔案中新增以下內容,指定Grpc服務型別為:Client
<ItemGroup> <Protobuf Include="Protos\greet.proto" GrpcServices="Client"/> <Protobuf Include="Protos\weatherforecast.proto" GrpcServices="Client" /> </ItemGroup>
3、新增呼叫Grpc服務程式碼:
class Program { static void Main(string[] args) { //初始化Grpc通道:引數為gRPC服務地址 using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new Greeter.GreeterClient(channel); var reply = client.SayHello( new HelloRequest { Name = "GreeterClient" }); Console.WriteLine("Greeting: " + reply.Message); //呼叫獲取天氣列表方法 Console.WriteLine("呼叫獲取天氣列表方法"); var wsClient = new Weather.WeatherClient(channel); var data = wsClient.GetWeatherList(new Empty()); foreach (var item in data.ListData) { Console.WriteLine($"天氣資訊:城市:{item.Summary},時間:{item.Date},溫度:{item.TemperatureC},華氏度:{item.TemperatureF}"); } //呼叫獲取天氣方法:帶引數 Console.WriteLine("呼叫獲取天氣方法:帶引數"); var result = wsClient.GetWeatherAsync(new WeatherRequest { Name = "Warm" }).ResponseAsync.Result; Console.WriteLine($"天氣資訊:城市:{result.Summary},時間:{result.Date},溫度:{result.TemperatureC},華氏度:{result.TemperatureF}"); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } }
4、呼叫結果如下:
四、總結
到此已完成gRPC服務的搭建和呼叫示例,採用gRPC呼叫服務非常方便,可以直接呼叫服務方法。
接下來還會進行更加深入的研究驗證。包括呼叫方式:服務端流式處理、客戶端流式處理、雙向流式處理等更加深入的用法
參考:
官方說明文件:https://grpc.io/docs/what-is-grpc/
微軟:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/?view=aspnetcore-3.0
示例原始碼地址:https://github.com/cwsheng/GrpcDemo