ASP.NET Core 3.0 gRPC 双向流

目录

  • ASP.NET Core 3.0 使用gRPC

  • ASP.NET Core 3.0 gRPC 双向流

  • ASP.NET Core 3.0 gRPC 认证授权

一.前言

在前一文 《

二. 什么是 gRPC 流

gRPC 有四种服务类型,分别是:简单 RPC(Unary RPC)、服务端流式 RPC (Server streaming RPC)、客户端流式 RPC (Client streaming RPC)、双向流式 RPC(Bi-directional streaming RPC)。它们主要有以下特点:

简单 RPC一般的rpc调用,传入一个请求对象,返回一个返回对象
服务端流式 RPC传入一个请求对象,服务端可以返回多个结果对象
客户端流式 RPC客户端传入多个请求对象,服务端返回一个结果对象
双向流式 RPC结合客户端流式RPC和服务端流式RPC,可以传入多个请求对象,返回多个结果对象

三.为什么 gRPC 支持流

gRPC 通信是基于 HTTP/2 实现的,它的双向流映射到 HTTP/2 流。HTTP/2 具有流的概念,流是为了实现HTTP/2的多路复用。流是服务器和客户端在HTTP/2连接内用于交换帧数据的独立双向序列,逻辑上可看做一个较为完整的交互处理单元,即表达一次完整的资源请求、响应数据交换流程;一个业务处理单元,在一个流内进行处理完毕,这个流生命周期完结。

特点如下:

  • 一个HTTP/2连接可同时保持多个打开的流,任一端点交换帧

  • 流可被客户端或服务器单独或共享创建和使用

  • 流可被任一端关闭

  • 在流内发送和接收数据都要按照顺序

  • 流的标识符自然数表示,1~2^31-1区间,有创建流的终端分配

  • 流与流之间逻辑上是并行、独立存在

摘自 HTTP/2笔记之流和多路复用 by 聂永

四.gRPC中使用双向流调用

我们在前文中编写的RPC属于简单RPC,没有包含流调用,下面直接讲一下双向流,根据第二小节列举的四种服务类型,如果我们掌握了简单RPC和双向流RPC,那么服务端流式 RPC和客户端流式 RPC自然也就没有问题了。

这里我们继续使用前文的代码,要实现的目标是一次给多个猫洗澡。

① 首先在 LuCat.proto 定义两个rpc,一个 Count 用于统计猫的数量,一个 双向流 RPC BathTheCat 用于给猫洗澡

syntax = "proto3";option csharp_namespace = "AspNetCoregRpcService";import "google/protobuf/empty.proto";
package LuCat;service LuCat{rpc BathTheCat(stream BathTheCatReq) returns ( stream BathTheCatResp);rpc Count(google.protobuf.Empty) returns (CountCatResult);
}message SuckingCatResult{string message=1;
}
message BathTheCatReq{int32 id=1;
}
message BathTheCatResp{string message=1;
}
message CountCatResult{int32 Count=1;
}

② 添加服务的实现

这里安利下Resharper,非常方便

640?wx_fmt=gif

private readonly ILogger<LuCatService> _logger;
private static readonly List<string> Cats=new List<string>(){"英短银渐层","英短金渐层","美短","蓝猫","狸花猫","橘猫"};
private static readonly Random Rand=new Random(DateTime.Now.Millisecond);public LuCatService(ILogger<LuCatService> logger)
{_logger = logger;
}public override async Task BathTheCat(IAsyncStreamReader<BathTheCatReq> requestStream, IServerStreamWriter<BathTheCatResp> responseStream, ServerCallContext context)
{var bathQueue=new Queue<int>();while (await requestStream.MoveNext()){bathQueue.Enqueue(requestStream.Current.Id);_logger.LogInformation($"Cat {requestStream.Current.Id} Enqueue.");}while (bathQueue.TryDequeue(out var catId)){await responseStream.WriteAsync(new BathTheCatResp() { Message = $"铲屎的成功给一只{Cats[catId]}洗了澡!" });await Task.Delay(500);}
}public override Task<CountCatResult> Count(Empty request, ServerCallContext context)
{return Task.FromResult(new CountCatResult(){Count = Cats.Count});
}

BathTheCat 方法会接收多个客户端发来的CatId,然后将他们加入队列中,等客户端发送完成后开始依次洗澡并返回给客户端。

③ 客户端实现

随机发送10个猫Id给服务端,然后接收10个洗澡结果。

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var catClient = new LuCat.LuCatClient(channel);var catCount = await catClient.CountAsync(new Empty());
Console.WriteLine($"一共{catCount.Count}只猫。");
var rand = new Random(DateTime.Now.Millisecond);var bathCat = catClient.BathTheCat();var bathCatRespTask = Task.Run(async() =>
{await foreach (var resp in bathCat.ResponseStream.ReadAllAsync()){Console.WriteLine(resp.Message);}
});for (int i = 0; i < 10; i++)
{await bathCat.RequestStream.WriteAsync(new BathTheCatReq() {Id = rand.Next(0, catCount.Count)});
}await bathCat.RequestStream.CompleteAsync();
Console.WriteLine("客户端已发送完10个需要洗澡的猫id");
Console.WriteLine("接收洗澡结果:");await bathCatRespTask;Console.WriteLine("洗澡完毕");

④ 运行

640?wx_fmt=gif

可以看到双向流调用成功,客户端发送了10个猫洗澡请求对象,服务端返回了10个猫洗澡结果对象。且是实时推送的,这就是 gRPC 的双向流调用。

这里大家可以自行改进来演变成客户端流式或者服务端流式调用。客户端发送一个猫Id列表,然后服务端返回每个猫洗澡结果,这就是服务端流式调用。客户端依次发送猫Id,然后服务端一次性返回所有猫的洗澡结果(给所有猫洗澡看做是一个业务,返回这个业务的结果),就是客户端流式调用。这里我就不再演示了。

五.流控制

gRPC 的流式调用支持对流进行主动取消的控制,进而可以衍生出流超时限制等控制。

在流式调用是,可以传一个 CancellationToken 参数,它就是我们用来对流进行取消控制的:

640?wx_fmt=png

改造一下我们在第四小节的代码:

① 客户端

var cts = new CancellationTokenSource();cts.CancelAfter(TimeSpan.FromSeconds(2.5));
var bathCat = catClient.BathTheCat(cancellationToken: cts.Token);var bathCatRespTask = Task.Run(async() =>
{try{await foreach (var resp in bathCat.ResponseStream.ReadAllAsync()){Console.WriteLine(resp.Message);}}catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled){Console.WriteLine("Stream cancelled.");}
});

② 服务端


while (!context.CancellationToken.IsCancellationRequested && bathQueue.TryDequeue(out var catId))
{_logger.LogInformation($"Cat {catId} Dequeue.");await responseStream.WriteAsync(new BathTheCatResp() { Message = $"铲屎的成功给一只{Cats[catId]}洗了澡!" });await Task.Delay(500);
}

③ 运行

640?wx_fmt=gif

设置的是双向流式调用2.5s后取消流,从客户端调用结果看到,并没有收到全部10个猫的洗澡返回结果,流就已经被取消了,这就是 gRPC 的流控制。

六.结束

这里流式调用可以实现实时推送,服务端到客户端或者客户端到服务端短实时推送消息,但是这个和传统意义上的长连接主动推送、广播消息不一样,不管你是服务端流式、客户端流式还是双向流式,必须要由客户端进行发起,通过客户端请求来建立流通信。

七.参考资料

  • GRPC的四种服务类型 by twtydgo

  • HTTP/2笔记之流和多路复用 by 聂永

  • 本文所用代码

原文链接:https://www.cnblogs.com/stulzq/p/11590088.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源公司被云厂商“寄生”,咋整?

上周 OSS Capital 召集一些开源公司&#xff0c;组织了一场关于如何面对“云厂商给开源带来的危害”的会议。OSS Capital 是一家风险投资公司&#xff0c;该公司只投开源&#xff0c;其董事会合伙人之一是开源运动的先驱人物 Bruce Perens。网上有一个十分有名的“开源商业化独…

Spring Cloud Config——原理解析

springCloud config项目,用来为分布式的微服务系统中提供集成式外部配置支持,分为客户端和服务端 可以让你把配置放到远程服务器&#xff0c;目前支持本地存储、Git以及Subversion。 spring官方如下介绍: 简而言之: 通过配置服务(Config Server)来为所有的环境和应用提供外部配…

AWS加入.NET Foundation企业赞助商计划

.NET 走向开源&#xff0c;MIT许可协议。 微软为了推动.NET开源社区的发展&#xff0c;2014年联合社区成立了.NET基金会。.NET基金会是一个独立的组织&#xff0c;支持.NET社区和开源&#xff0c;旨在拓宽和加强.NET生态系统和社区。这可以通过多种方式完成&#xff0c;包括项目…

Spring cloud——Hystrix 原理解析

1、背景 分布式系统环境下&#xff0c;服务间类似依赖非常常见&#xff0c;一个业务调用通常依赖多个基础服务。如下图&#xff0c;对于同步调用&#xff0c;当库存服务不可用时&#xff0c;商品服务请求线程被阻塞&#xff0c;当有大批量请求调用库存服务时&#xff0c;最终可…

【B】替换 Quartz.net 默认使用的 MySql.Data 为 Mysqlconnector 的学习过程

文章转载授权级别&#xff1a;B无论是 Quartz.net 还是 MySql.Data 都是我们比较熟悉的库了&#xff0c;Quartz.net 如果配置为使用 MySql 数据库做持久化时&#xff0c;默认是硬编码了使用 MySql.Data 来操作 MySql 数据库的。下面是我的一些个人诉求和实践&#xff0c;和大家…

APM(应用性能管理)与Dapper原理介绍

一、APM&#xff08;应用性能管理&#xff09; 1.1 什么是APM&#xff1f; APM (Application Performance Management) 即应用性能管理&#xff08;应用性能监控&#xff09; APM主要是针对企业 关键业务的IT应用性能和用户体验的监测、优化&#xff0c;提高企业IT应用的可靠…

asp.netcore3.0 使用 DbProviderFactories 连接数据库

在.netstandard2.0时 System.Data.Common 这个包里并没有加入DbProviderFactoriesDbProviderFactories类在.netframework中是非常重要的存在,依靠他可以适配各种数据库客户端&#xff08;sqlserver、mysql、sqllite等&#xff09;创建数据库连接。现在可以像.netframework中一样…

MIT 6.824 Lab 1 MapReduce

MapReduce 目标 根据论文所说明的&#xff0c;有MASTER和WORKER两类工作节点&#xff0c;以下实现大都按照论文所说的实现&#xff0c;但是在对MASTER的实现上有所改动&#xff1a; MASTER向WORKER发送心跳检测&#xff0c;这里改为了对分配出去的任务进行超时监控。 MASTER…

大家在寻找的高级程序员到底是什么样子的?

你好&#xff0c;我是Z哥。这篇文章主题很简单&#xff0c;就是一个很常见的话题“什么是高级程序员&#xff1f;”。文章稍微长了些&#xff0c;但是很容易阅读。我们的中国文化&#xff0c;对“面子”看的特别重&#xff0c;所以你会发现身边到处都是高级XXX&#xff0c;听着…

优秀的程序员是那种过单行线马路都要往两边看的人

最近一周帮我以前一个同事推荐工作&#xff0c;顺便了解下行情&#xff0c;我这个同事我感觉还行&#xff0c;技术不说有多好&#xff0c;但是往年绝对不至于简历筛选时被刷掉那种&#xff0c;最先开始推给了一个我比较信任的HR手里&#xff0c;她兼职猎头&#xff0c;推给这个…

【为自己相亲】单身小姐姐你在哪里,我是书豪,我在等你

笔者简介Introduction书豪&#xff1a;【人工智能爱好者社区】公众号负责人《R数据科学实战&#xff1a;工具详解与案例分析》书籍作者。 你没看错这是书豪在给自己寻觅良缘如果你有&#xff0c;或者身边的朋友有兴趣请与我联系基本信息 出生日期&#xff1a;1995年5月身高&am…

知道的越多,越感觉自己渺小

作者&#xff1a;猛哥&#xff0c;关注技术和人文发展的程序员&#xff0c;架构师社区合伙人芝诺说&#xff1a;“人的知识就像一个圆&#xff0c;圆圈外是未知的&#xff0c;圆圈内是已知的&#xff0c;你知道的越多&#xff0c;你的圆圈就会越大。圆的周长也就越大&#xff0…

.NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题及解决办法

行为不一致.NET Core 3.0 新出了个内置的 JSON 库, 全名叫做尼古拉斯 System.Text.Json - 性能更高占用内存更少这都不是事...对我来说, 很多或大或小的项目能少个第三方依赖项, 还能规避多个依赖项的依赖 Newtonsoft.Json 版本不一致的问题, 是件极美的事情.但是, 结果总不是不…

Java9 新特性

在介绍 java9 之前&#xff0c;我们先来看看java成立到现在的所有版本。 1990年初&#xff0c;最初被命名为Oak&#xff1b;1995年5月23日&#xff0c;Java语言诞生&#xff1b;1996年1月&#xff0c;第一个JDK-JDK1.0诞生&#xff1b;1996年4月&#xff0c;10个最主要的操作系…

深入探究Kubernetes - 初识容器

♥2019年8月28星期三第47篇原创引言最近Kubernetes比较火&#xff0c;新技术快速火起来&#xff0c;一定有它强大的优势&#xff0c;Hr反馈&#xff0c;招聘时会Kubernetes的很少&#xff0c;风口上的Kubernetes一起学学&#xff1f;扫盲贴&#xff0c;参考《Kubernetes进阶实践…

Java11 新特性

Java 11新特性的详细解释。JDK 11已经于 2018年9月25日正式发布&#xff0c;那么Java 11主要包含哪些新特性呢&#xff1f; JDK 11是Java SE 11平台版本11的开源参考实现&#xff0c;由JSR 384在Java Community Process中指定。 阿里巴巴是中国唯一的JCP委员会成员公司&#x…

福爆 | 博客升级 .NET Core 3.0 又踩一坑

点击上方蓝字关注“汪宇杰博客”导语昨天刚发了一篇《生产大爆炸发生问题的是已经被删除的博客文章&#xff0c;正常情况下&#xff0c;这些不存在的文章会直接显示自定义的404页面&#xff0c;但实际上产生了500异常。日志如下&#xff1a;2019-09-26 00:11:50.8405|RD00155DB…

Sping5——响应式编程

1、响应式编程基础 1.1、什么是响应式编程&#xff1f; 响应式编程是一种面向数据流和变化传播的编程范式。 使用它可以在编程语言中很方便地表达静态或动态的数据流&#xff0c;而相关的计算模型会自动将变化的值通过数据流进行传播。我们可以使用声明的方式构建应用程序的能…

.NET Core使用NPOI导出复杂Word详解

最近使用NPOI做了个导出Word文档的功能&#xff0c;关于使用.NET Core 导出Word文档的方式有很多。最终我为什么选择了NPOI来实现了这个功能&#xff0c;首先是NPOI是一个开源&#xff0c;免费且容易上手的第三方框架&#xff08;并且现在已支持.NET Core&#xff0c;GitHub源码…

Spring Boot 2.0新特性

Spring Boot依赖于Spring&#xff0c;而Spring Cloud又依赖于Spring Boot&#xff0c;因此Spring Boot2.0的发布正式整合了Spring5.0的很多特性&#xff0c;同样后面Spring Cloud最新版本的发布也需要整合最新的Spring Boot2.0内容。 一、新版本特性 1.1&#xff0c;基于 Jav…