gRPC在 ASP.NET Core 中應用學習

1、gRPC簡介:

 gRPC 是一個由Google開源的,跨語言的,高性能的遠程過程調用(RPC)框架。 gRPC使客戶端和服務端應用程序能夠透明地進行通訊,並簡化了鏈接系統的構建。它使用HTTP/2做爲通訊協議,使用 Protocol Buffers(協議緩衝區) 做爲序列化協議。git

 引用自微軟文檔:github

gRPC 的主要優勢是:服務器

  • 現代高性能輕量級 RPC 框架。
  • 協定優先 API 開發,默認使用協議緩衝區,容許與語言無關的實現。
  • 可用於多種語言的工具,以生成強類型服務器和客戶端。
  • 支持客戶端、服務器和雙向流式處理調用。
  • 使用 Protobuf 二進制序列化減小對網絡的使用。

這些優勢使 gRPC 適用於:網絡

  • 效率相當重要的輕量級微服務。
  • 須要多種語言用於開發的 Polyglot 系統。
  • 須要處理流式處理請求或響應的點對點實時服務。

 官方支持的gRPC語言,平臺和操做系統版本app

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+

2、ASP.NET 中gRPC應用:

 一、建立gRPC服務項目:新建項目框架

  二、建立項目代碼解析:dom

  如圖能夠看到建立目錄中:主要添加:greet.proto、GreeterServiceasync

  a)greet.proto文件說明:    ide

//指定協議緩衝區使用版本
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"
    }
  }     

  三、建立本身的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服務:

    

3、客戶端調用gRPC服務

 一、建立.net core控制檯應用;並添加nuget包引用  

Install-Package Grpc.Net.Client
Install-Package Google.Protobuf
Install-Package Grpc.Tools

 二、將服務端中Protos文件,拷貝到客戶端中,並在項目文件中添加如下內容,指定Grpc服務類型爲:Client

<ItemGroup>
    <Protobuf Include="Protos\greet.proto" GrpcServices="Client"/>
    <Protobuf Include="Protos\weatherforecast.proto" GrpcServices="Client" />
</ItemGroup>

 三、添加調用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

相關文章
相關標籤/搜索