Dapr 运用之集成 Asp.Net Core Grpc 调用篇

前置条件: 《Dapr 运用》

改造 ProductService 以提供 gRPC 服务

从 NuGet 或程序包管理控制台安装 gRPC 服务必须的包

Grpc.AspNetCore

配置 Http/2

gRPC 服务需要 Http/2 协议

public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureKestrel(options => { options.Listen(IPAddress.Loopback, 5001, listenOptions => { listenOptions.Protocols = HttpProtocols.Http2; }); }); webBuilder.UseStartup<Startup>(); }); }

新建了 product.proto 以定义 GRPC 服务,它需要完成的内容是返回所有产品集合,当然目前产品内容只有一个 ID

定义产品 proto

syntax = "proto3"; package productlist.v1; option csharp_namespace = "ProductList.V1"; service ProductRPCService{ rpc GetAllProducts(ProductListRequest) returns(ProductList); } message ProductListRequest{ } message ProductList { repeated Product results = 1; } message Product { string ID=1; } 说明

定义产品列表 gRPC 服务,得益于宇宙第一 IDE Visual Studio ,只要添加 Grpc.Tools 包就可以自动生成 gRPC 所需的代码,这里不再需要手动去添加 Grpc.Tools ,官方提供的 Grpc.AspNetCore 中已经集成了

定义了一个服务 ProductRPCService

定义了一个函数 ProductRPCService

定义了一个请求构造 ProductListRequest ,内容为空

定义了一个请求返回构造 ProductList ,使用 repeated 表明返回数据是集合

定义了一个数据集合中的一个对象 Product

添加 ProductListService 文件,内容如下

public class ProductListService : ProductRPCService.ProductRPCServiceBase { private readonly ProductContext _productContext; public ProductListService(ProductContext productContext) { _productContext = productContext; } public override async Task<ProductList.V1.ProductList> GetAllProducts(ProductListRequest request, ServerCallContext context) { IList<Product> results = await _productContext.Products.ToListAsync(); var productList = new ProductList.V1.ProductList(); foreach (Product item in results) { productList.Results.Add(new ProductList.V1.Product { ID = item.ProductID.ToString() }); } return productList; } }

在 Startup.cs 修改代码如下

public void ConfigureServices(IServiceCollection services) { //启用 gRPC 服务 services.AddGrpc(); services.AddTransient<ProductListService>(); ... }

这里的 services.AddTransient(); 的原因是在 Dapr 中需要使用构造器注入,以完成 GetAllProducts(...) 函数的调用

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseEndpoints(endpoints => { ... //添加 gRPC 到路由管道中 endpoints.MapGrpcService<DaprClientService>(); }); }

这里添加的代码的含义分别是启用 gRPC 服务和添加 gRPC 路由。得益于 ASP.NET Core 中间件的优秀设计,ASP.NET Core 可同时支持 Http 服务。

添加 daprclient.proto 文件以生成 Dapr Grpc 服务,daprclient.proto 内容如下

syntax = "proto3"; package daprclient; import "google/protobuf/any.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/duration.proto"; option java_outer_classname = "DaprClientProtos"; option java_package = "io.dapr"; // User Code definitions service DaprClient { rpc OnInvoke (InvokeEnvelope) returns (google.protobuf.Any) {} rpc GetTopicSubscriptions(google.protobuf.Empty) returns (GetTopicSubscriptionsEnvelope) {} rpc GetBindingsSubscriptions(google.protobuf.Empty) returns (GetBindingsSubscriptionsEnvelope) {} rpc OnBindingEvent(BindingEventEnvelope) returns (BindingResponseEnvelope) {} rpc OnTopicEvent(CloudEventEnvelope) returns (google.protobuf.Empty) {} } message CloudEventEnvelope { string id = 1; string source = 2; string type = 3; string specVersion = 4; string dataContentType = 5; string topic = 6; google.protobuf.Any data = 7; } message BindingEventEnvelope { string name = 1; google.protobuf.Any data = 2; map<string,string> metadata = 3; } message BindingResponseEnvelope { google.protobuf.Any data = 1; repeated string to = 2; repeated State state = 3; string concurrency = 4; } message InvokeEnvelope { string method = 1; google.protobuf.Any data = 2; map<string,string> metadata = 3; } message GetTopicSubscriptionsEnvelope { repeated string topics = 1; } message GetBindingsSubscriptionsEnvelope { repeated string bindings = 1; } message State { string key = 1; google.protobuf.Any value = 2; string etag = 3; map<string,string> metadata = 4; StateOptions options = 5; } message StateOptions { string concurrency = 1; string consistency = 2; RetryPolicy retryPolicy = 3; } message RetryPolicy { int32 threshold = 1; string pattern = 2; google.protobuf.Duration interval = 3; } 说明

此文件为官方提供,Dapr 0.3 版本之前提供的已经生成好的代码,现在看源码可以看出已经改为提供 proto 文件了,这里我认为提供 proto 文件比较合理

此文件定义了5个函数,此文主要讲的就是 OnInvoke() 函数

OnInvoke() 请求构造为 InvokeEnvelope

method 提供调用方法名称

data 请求数据

metadata 额外数据,此处使用键值对形式体现

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpgfjs.html