tnblog
首页
视频
资源
登录

Dapr .NetCore grpc调用

9598人阅读 2021/10/10 12:21 总访问:3252774 评论:0 收藏:0 手机
分类: .net后台框架

Dapr .NetCore grpc调用


本文介绍如何使用 Dapr 连接使用 gRPC 的服务。通过使用 Dapr 的 gRPC 代理功能,您可以使用现有的基于 proto 的 gRPC 服务并使流量通过 Dapr sidecar。这样做会给开发人员带来以下Dapr 服务调用的好处:

1.相互认证
2.追踪
3.指标
4.访问列表
5.网络级弹性
6.基于 API 令牌的身份验证

创建运行 gRPC 服务器

创建项目


执行如下命令添加grpc服务器项目

  1. dotnet new grpc -n InvokeMethodGRPCServer

修改项目监听端口


修改launchSettings.json中监听端口为5003,避免与我们客户端监听端口产生冲突(5001)。

  1. {
  2. "profiles": {
  3. "InvokeMethodGRPCServer": {
  4. "commandName": "Project",
  5. "launchBrowser": false,
  6. "applicationUrl": "http://localhost:5003",
  7. "environmentVariables": {
  8. "ASPNETCORE_ENVIRONMENT": "Development"
  9. }
  10. }
  11. }
  12. }


在Program文件中,添加grpc监听端口5050

  1. public static IHostBuilder CreateHostBuilder(string[] args) =>
  2. Host.CreateDefaultBuilder(args)
  3. .ConfigureWebHostDefaults(webBuilder =>
  4. {
  5. webBuilder.ConfigureKestrel(options =>
  6. {
  7. options.ListenLocalhost(5050, o => o.Protocols =
  8. HttpProtocols.Http2);
  9. });
  10. webBuilder.UseStartup<Startup>();
  11. });

添加依赖

  1. <ItemGroup>
  2. <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
  3. <PackageReference Include="Dapr.AspNetCore" Version="1.4.0" />
  4. <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
  5. <PackageReference Include="Google.Api.CommonProtos" Version="2.4.0" />
  6. </ItemGroup>

创建grpc服务


在创建项目时,我们看见了Services目录下创建了/Protos/greet.proto所对应的GreeterService,我们只需要调用它的SayHello方法即可

  1. public class GreeterService : Greeter.GreeterBase
  2. {
  3. private readonly ILogger<GreeterService> _logger;
  4. public GreeterService(ILogger<GreeterService> logger)
  5. {
  6. _logger = logger;
  7. }
  8. public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
  9. {
  10. return Task.FromResult(new HelloReply
  11. {
  12. Message = "Hello " + request.Name
  13. });
  14. }
  15. }


Services目录下面创建DaprClientService服务实现AppCallback.AppCallbackBase,让Dapr识别到grpc的服务的sayhello方法。

  1. public class DaprClientService:AppCallback.AppCallbackBase
  2. {
  3. private readonly GreeterService _service;
  4. private readonly DaprClient _daprclient;
  5. public DaprClientService(
  6. GreeterService service,
  7. DaprClient daprclient
  8. ){
  9. _service = service;
  10. _daprclient = daprclient;
  11. }
  12. public override async Task<InvokeResponse> OnInvoke(InvokeRequest request, ServerCallContext context)
  13. {
  14. var response = new InvokeResponse();
  15. switch (request.Method)
  16. {
  17. case "sayhello":
  18. if (request.Data.TryUnpack<HelloRequest>(out HelloRequest input))
  19. {
  20. var output = await _service.SayHello(input,context);
  21. response.Data = Any.Pack(output);
  22. }
  23. break;
  24. default:
  25. break;
  26. }
  27. return response;
  28. }
  29. public override Task<ListInputBindingsResponse> ListInputBindings(Empty request, ServerCallContext context)
  30. {
  31. return base.ListInputBindings(request, context);
  32. }
  33. public override Task<ListTopicSubscriptionsResponse> ListTopicSubscriptions(Empty request, ServerCallContext context)
  34. {
  35. var result = new ListTopicSubscriptionsResponse();
  36. result.Subscriptions.Add(new TopicSubscription
  37. {
  38. PubsubName = "pubsub",
  39. Topic = "sayhello"
  40. });
  41. return Task.FromResult(result);
  42. }
  43. public override Task<BindingEventResponse> OnBindingEvent(BindingEventRequest request, ServerCallContext context)
  44. {
  45. return base.OnBindingEvent(request, context);
  46. }
  47. public override Task<TopicEventResponse> OnTopicEvent(TopicEventRequest request, ServerCallContext context)
  48. {
  49. return base.OnTopicEvent(request, context);
  50. }
  51. }


这里我们需要注入DaprClientGreeterService,但是我们这里并没有对其服务进行注入,所以我们还需要在Startup类中添加相关服务的依赖注入。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddGrpc();
  4. services.AddDaprClient();
  5. services.AddTransient<GreeterService>();
  6. }
  7. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  8. {
  9. if (env.IsDevelopment())
  10. {
  11. app.UseDeveloperExceptionPage();
  12. }
  13. app.UseRouting();
  14. app.UseEndpoints(endpoints =>
  15. {
  16. endpoints.MapGrpcService<DaprClientService>();
  17. endpoints.MapGet("/", async context =>
  18. {
  19. 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");
  20. });
  21. });
  22. }


首先我们需要在ListTopicSubscriptions方法中,发布sayhello的订阅。

  1. public override Task<ListTopicSubscriptionsResponse> ListTopicSubscriptions(Empty request, ServerCallContext context)
  2. {
  3. var result = new ListTopicSubscriptionsResponse();
  4. result.Subscriptions.Add(new TopicSubscription
  5. {
  6. PubsubName = "pubsub",
  7. Topic = "sayhello"
  8. });
  9. return Task.FromResult(result);
  10. }


然后我们需要在OnInvoke方法中实现sayHello方法的调用;通过request.Method的判断方法的名称进行调用不同的case,通过TryUnpack方法转换将上传的数据转换成指定类型,我们看到SayHello方法是需要HelloRequest类型去进行接受的,所以我们把它转换成指定的类型。
然后,通过output变量获取GreeterService服务的SayHello方法的回调。
最后将回调的数据结果用Any.Pack转换成Any类型,进行返回。

  1. public override async Task<InvokeResponse> OnInvoke(InvokeRequest request, ServerCallContext context)
  2. {
  3. var response = new InvokeResponse();
  4. switch (request.Method)
  5. {
  6. case "sayhello":
  7. if (request.Data.TryUnpack<HelloRequest>(out HelloRequest input))
  8. {
  9. var output = await _service.SayHello(input,context);
  10. response.Data = Any.Pack(output);
  11. }
  12. break;
  13. default:
  14. break;
  15. }
  16. return response;
  17. }

运行grpc服务器


告诉dapr运行的appid为grpcserver且为grpc服务器,应用grpc开放的端口为5050,dapr的端口为3500

  1. dapr run --app-id grpcserver --app-protocol grpc --app-port 5050 --dapr-http-port 3500 -- dotnet run

创建客户端


这里我用创建好的InvokeMethod webapi项目。
首先将grpc Protos复制到该项目中,并进行添加相关依赖包与引用。
添加相关服务。

  1. <Project Sdk="Microsoft.NET.Sdk.Web">
  2. <PropertyGroup>
  3. <TargetFramework>netcoreapp3.1</TargetFramework>
  4. </PropertyGroup>
  5. <ItemGroup>
  6. <Protobuf Include="Protos\greet.proto" GrpcServices="Client" ProtoRoot="Protos\" />
  7. </ItemGroup>
  8. <ItemGroup>
  9. <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
  10. <PackageReference Include="Dapr.AspNetCore" Version="1.4.0" />
  11. <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
  12. </ItemGroup>
  13. </Project>
  1. services.AddControllers().AddDapr();


随后执行dotnet build进行生成相关类。

创建控制器


创建SendMessageGRPCController控制器,在请求Get方法时进行调用grpc的sayhello方法。

  1. [ApiController]
  2. [Route("[controller]")]
  3. public class SendMessageGRPCController
  4. {
  5. private readonly ILogger<SendMessageGRPCController> _logger;
  6. private readonly DaprClient _client;
  7. public SendMessageGRPCController(ILogger<SendMessageGRPCController> logger,DaprClient client )
  8. {
  9. _logger = logger;
  10. _client = client;
  11. }
  12. [HttpGet]
  13. public async Task<string> Get()
  14. {
  15. var request = new HelloRequest(){
  16. Name = "GRPC_Client"
  17. };
  18. // appid 方法名
  19. var result = await _client.InvokeMethodGrpcAsync<HelloRequest,HelloReply>("grpcserver","sayhello",request);
  20. return $"ok! {result.Message}";
  21. }
  22. }

运行客户端

  1. dapr run --app-id myclient --app-port 5001 --dapr-http-port 3501 -- dotnet run

查看启动的应用

测试


访问客户端的http://localhost:5001/SendMessageGRPC,我们可以看到grpc调用成功


在来Zipin上查看调用情况


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价

vs2017 对 COM 组件的调用返回了错误 HRESULT E_FAIL

vs2017添加引用报错 对 COM 组件的调用返回了错误 HRESULT E_FAIL 1.以管理员身份打开vs2017开发人员命令指示符 2...

微信开发三 使用反射根据消息类型自动调用不同方法

微信只会向我们一个地方推送消息,如果全部逻辑都写到一起,代码会非常多。所以我们可以考虑通过消息类型,来实现不同的消...

AJAX调用webapi上传图片或文件。设置token,设置Authorization Bearer

AJAX调用webapi上传图片或文件,并返回刚上传的文件名。废话不多说直接贴代码吧html相关:&lt;!DOCTYPEhtml&gt; &lt;html&...

当浏览器调用第三方设备时必须要用到PWA

说白了,调用页面要引用两个文件下面地址进行下载,默认第一个https://www.pwabuilder.com/serviceworker如想对PWA有过多了...

封装调用api接口的通用方法(抱含存调用接口日志)

protectedstaticreadonlylog4net.ILog_log=log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod(...

后台调用菜单接口+自定义菜单

假如有一天你喝醉了,一个人走在街头,会歇斯底里的喊出谁的名字?时光如流水般逝去,站在青春的末稍,扭过头,观望曾经走...

WebAPI调用post传值

创建core项目在项目中创建文件夹。在文件夹中创建webapi控制器,定义好路由。在页面上引入js文件。通过ajax调用api后台方法...

WebAPI调用Put传值

创建core项目在项目中创建文件夹。在文件夹中创建webapi控制器,定义好路由。在页面上引入js文件。通过ajax调用api后台方法...

WebAPI调用Delete传值

结合之前post,put方式,综上所述。首先路由传id。在方法里面定义参数在前台使用ajax传值调试进去则成功了不使用路由直接传...

.net core发布gRPC项目和远程调用

发布gRPC项目的过程和其他项目一样,右键发布即可发布出来后会看到有个.exe的程序然后直接丢到服务器双击运行即可不放到iis...

c调用百度AI通用物体和场景识别

publicclassAdvancedGeneral { //通用物体和场景识别 publicstaticAdvancedGeneralModeladvancedGeneral(stringtoken) ...

c调用百度AI银行卡识别

code:publicclassBankCard { //银行卡识别 publicstaticBankCardModelbankCard(stringtoken) { stringhost=&quot;http...

c调用百度AI手写文字识别

封装调用接口代码:publicclassBaiduAIBase64Tool { publicstaticstringInvoke(stringurl,stringimgurl) { //stringhos...

c调用百度AI新闻摘要接口

代码如下:publicclassNewsSummaryTools { publicstaticJObjectGetNewsSummary(stringtoken) { HttpClienthttpClient=n...

c调用百度AI文章标签识别

code:publicclassArticleTag { ///&lt;summary&gt; ///访问文章标签接口 ///&lt;/summary&gt; ///&lt;paramname=&quot...

c调用阿里云实现图像打标

url方式:publicvoidInvoke() { //ak,sk信息设置 stringak_id=&quot;yourak_id&quot;; stringak_secret=&quot;yourak_s...
这一世以无限游戏为使命!
排名
8
文章
191
粉丝
7
评论
7
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术