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