gRPC在 ASP.NET Core 中應用學習(一)


一、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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM