• gRPC在 ASP.NET Core 中应用学习(一)


    一、gRPC简介:

     gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架。 gRPC使客户端和服务端应用程序可以透明地进行通信,并简化了连接系统的构建。它使用HTTP/2作为通信协议,使用 Protocol Buffers(协议缓冲区) 作为序列化协议。

     引用自微软文档:

    gRPC 的主要优点是:

    • 现代高性能轻量级 RPC 框架。
    • 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
    • 可用于多种语言的工具,以生成强类型服务器和客户端。
    • 支持客户端、服务器和双向流式处理调用。
    • 使用 Protobuf 二进制序列化减少对网络的使用。

    这些优点使 gRPC 适用于:

    • 效率至关重要的轻量级微服务。
    • 需要多种语言用于开发的 Polyglot 系统。
    • 需要处理流式处理请求或响应的点对点实时服务。

     官方支持的gRPC语言,平台和操作系统版本

    LanguageOSCompilers / 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文件自动生成的,生成的类在 objDebug etcoreapp3.1目录下    

    //Greeter.GreeterBase由grpc.tools根据proto文件自动生成。
    //文件路径在:objdebug
    etcoreapp3.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="Protosgreet.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="Protosgreet.proto" GrpcServices="Client"/>
        <Protobuf Include="Protosweatherforecast.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

  • 相关阅读:
    使用Ant Design的Table和Checkbox模拟Tree
    js中的按位取反运算符~
    Antd的Table组件嵌套Table以及选择框联动
    antd的Select,DatePicker,Cascader等组件选项框随页面滚动的问题解决
    Promise简介以及常用方法
    js一键复制文本
    react中使用pre标签不生效的解决方法
    使用html2canvas将html通过canvas转换成图片
    谷歌浏览器新开页面进程问题
    如何使用Context
  • 原文地址:https://www.cnblogs.com/cwsheng/p/14495453.html
Copyright © 2020-2023  润新知