ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

640?wx_fmt=jpeg

早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把。同时记录体验的过程。如果你也想按照本文的步骤体验的话,那你得先安装.NET Core3.0预览版的SDK。至于开发工具我用的时VS2019,当然你也可以使用VS Code进行。

作者:依乐祝
原文地址:https://www.cnblogs.com/yilezhu/p/10631420.html

gRPC的简单介绍

gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架。 有关 gRPC 基础知识的详细信息,请参阅 gRPC 文档页。

gRPC 的主要优点是:

  • 现代高性能轻量级 RPC 框架。

  • 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。

  • 可用于多种语言的工具,以生成强类型服务器和客户端。

  • 支持客户端、服务器和双向流式处理调用。

  • 使用 Protobuf 二进制序列化减少对网络的使用。

这些优点使 gRPC 适用于:

  • 效率至关重要的轻量级微服务。

  • 需要多种语言用于开发的 Polyglot 系统。

  • 需要处理流式处理请求或响应的点对点实时服务。

ASP.NET Core 3.0上gRPC服务模板初体验

创建gRPC服务

  1. 打开VS2019 从 Visual Studio“文件”菜单中选择“新建” > “项目”。(由于我是新打开的VS,所以按照如下图所示创建新项目)

    640?wx_fmt=png

  2. 如下图所示,选择创建《ASP.NET Core Web 应用程序》,然后点击下一步

    640?wx_fmt=png

  3. 在此页面按照下图所示,输入项目名称,位置,解决方案名称,然后点击右下角的“创建”按钮进行创建。

    640?wx_fmt=png

  4. 你以为上述步骤中点击“创建”就结束了嘛?说好的要创建gRPC服务模板的,所以,点击上面的创建后会弹出如下图所示,让你选择服务模板的窗口,这里按照下图所示选择gRPC服务模板,然后再次点击右下角的创建,才是真正的创建项目。

    640?wx_fmt=png

  5. 创建成功后,会出现如下图所示的项目结构

    640?wx_fmt=png

  6. 至此,我们就创建好了一个gRPC服务的模板,接下来我们先测试一番,然后再好好的看下这个模板的结构吧

测试gRPC服务

  1. 首先打开HelloGrpc.Server 这个服务端的工作目录,然后Shift+鼠标右键弹出如下图所示的右键菜单,如图所示打开ps窗口

    640?wx_fmt=png

  2. 输入dotnet run 命令运行此gRPC服务端项目,如下图所示,说明服务端启动正常,并开始监听对应的端口。

    640?wx_fmt=png

  3. 同样的方法,我们启动客户端,这时候客户端会向该服务端发送一条包含具有其名称“GreeterClient”的消息的问候信息。 该服务端将发送一条消息“Hello GreeterClient”作为响应,并显示在命令提示符中。如下图所示:

    640?wx_fmt=png

  4. 至此,gRPC服务模板创建的服务端以及客户端测试成功。下面我们就好好的探究一下这个服务模板吧。

gRPC模板解析

HelloGrpc.Server 服务的端项目中有如下几个文件

  • greet.proto:greet.proto 文件定义 Greeter gRPC,且用于生成 gRPC 服务器资产。

  • Services 文件夹:包含 Greeter 服务的实现。

  • appSettings.json:包含配置数据,如 Kestrel 使用的协议。(熟悉ASP.NET Core的你一定很熟悉)

  • Program.cs:包含 gRPC 服务的入口点。(熟悉ASP.NET Core的你一定很熟悉)

  • Startup.cs:IWebHostBuilder的启动配置文件,包含配置应用行为的代码。(熟悉ASP.NET Core的你一定很熟悉)

gRPC 客户端 HelloGrpc.Client 文件:

Program.cs 包含 gRPC 客户端的入口点和逻辑。

下面我们再打开每个文件看看里面究竟是什么东东吧。

proto文件

proto

GRPC使用约定优先的API开发方法。默认情况下,使用协议缓冲区(Protobuf)作为接口设计语言(IDL)。这个.proto文件包含:

  • GRPC服务的定义。

  • 在客户端和服务器之间发送的消息。

有关Protobuf文件语法的更多信息,请参见正式文件(原型).

如我们模板中创建的greet.proto 文件内容如下:

syntax = "proto3";

package Greet;

// The greeting service definition.
service Greeter {
// Sends a greeting
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;
}
  • 定义Greeter服务。

  • 这个Greeter服务定义SayHello请求。

  • SayHello发送HelloRequest消息并接收HelloResponse信息:
    那么你可能要问了,这个.proto文件是如何包含在项目中的呢,其实,如果你打开.csproject文件就会看到,通过将该文件添加到<Protobuf>的ItemGroup中即可,如下所示:

<ItemGroup>
<Protobuf Include="..\Protos\*.proto" GrpcServices="Server" />
<Content Include="@(Protobuf)" LinkBase="" />
</ItemGroup>

C#对.proto文件的工具支持

工具包Grpc.Tools 被用来从.proto文件生成C#文件。生成的资产(文件)具有如下特性:

  • 每次构建项目时都会根据需要进行生成。

  • 生成的文件不会被添加到项目或签入源代码管理。

  • 生成的C#文件是包含在OBJ目录。

服务器和客户端项目都需要此包。Grpc.Tools可以通过在VisualStudio中使用包管理器或添加<PackageReference>到项目文件:

XML复制

<PackageReference Include="Grpc.Tools" Version="1.19.0-pre1" PrivateAssets="All" />

工具包在运行时并不是必需的,因此,应该用PrivateAssets="All".

Services 文件夹中的具体的gRPC服务

我们知道Grpc.Tools工具包将根据.proto文件的定义翻译并生成对应的C#类型的文件。

对于服务器端资产,将生成一个抽象的服务基类型。基类型包含在.proto文件中包含的所有GRPC调用的定义。然后,您将创建从此基类型派生的具体服务实现,并实现GRPC调用的逻辑。对于前面描述的greet.proto示例,将生成包含虚拟SayHello方法的抽象GreeterBase类型。具体的实现GreeterService重写该方法并实现处理GRPC调用的逻辑。
正如HelloGrpc.Server项目中的Services\GreeterService.cs中的代码

public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply>
SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}

对于客户端,将生成一个具体的客户端类型中的GRPC调用。.proto文件被转换为可以调用的具体类型上的方法。为greet.proto前面描述的示例,一个具体的GreeterClient类型生成。这个GreeterClient类型包含SayHello方法,可以调用该方法来启动对服务器的GRPC调用。

public class Program
{
static async Task Main(string[] args)
{
// Include port of the gRPC server as an application argument
var port = args.Length > 0 ? args[0] : "50051";

var channel = new Channel("localhost:" + port, ChannelCredentials.Insecure);
var client = new Greeter.GreeterClient(channel);

var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);

await channel.ShutdownAsync();

Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}

默认情况下,分别生成服务器和客户端资产。.proto文件包含在<Protobuf>项目组。若要确保仅在服务器项目中生成服务器资产,GrpcServices属性设置为Server.

XML复制

<ItemGroup>
<Protobuf Include="..\Protos\*.proto" GrpcServices="Server" />
<Content Include="@(Protobuf)" LinkBase="" />
</ItemGroup>

类似地,属性设置为Client在仅在客户项目中生成。

Startup

Startup中我们发现跟普通的ASP.NET Core程序有所不同,具体的如下图所示:在ConfigureServices 服务中引入了gRPC服务,然后在Configure加入了路由

640?wx_fmt=png

而这里需要引入三个与gRPC相关的nuget包

  • Grpc.AspNetCore.Server

  • Google.Protobuf对于Protobuf消息API。

  • Grpc.Tools

这里需要说明的是

ASP.NET Core 中间件和功能共享路由管道,因此可以将应用程序配置为服务其他请求处理程序。其他请求处理程序(如MVC控制器)可以与配置的GRPC服务路由并行工作。

其他需要说明的内容

与ASP.NET Core 接口的集成

GRPC服务可以完全访问ASP.NETCore功能,如依赖注入(Di)和日志功能。例如,服务实现可以通过构造函数解析DI容器中的记录器服务:

public class GreeterService : Greeter.GreeterBase
{
public GreeterService(ILogger<GreeterService> logger)
{
}
}

默认情况下,GRPC服务可以解析具有任意生存期的其他DI服务(Singleton, Scoped, or Transient)。

在GRPC方法中解析HttpContext

GRPC 应用程序接口提供对某些HTTP/2消息数据的访问,例如method, host, header, and trailers。访问是通过ServerCallContext参数传递给每个GRPC方法:

public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply>
SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}

ServerCallContext不提供对所有ASP.NET 接口中HttpContext的完全访问。GetHttpContext扩展方法提供对表示ASP.NET API中底层HTTP/2消息的httpContext的完全访问:

public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request,
ServerCallContext context
)
{
var httpContext = context.GetHttpContext();

return Task.FromResult(new HelloReply
{
Message = "Using https: " + httpContext.Request.IsHttps
});
}
}

请求体数据速率限制

默认情况下,Kestrel服务器设置为最小请求主体数据速率。对于客户端流式和双工流式的请求,此速率可能不满足,并且连接可能超时。当GRPC服务包括客户端流和双工流调用时,必须禁用最小请求正文数据速率限制:

public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel((context, options) =>
{
options.Limits.MinRequestBodyDataRate = null;
});
});
}

参考文章

  • gRPC services with C#

  • Tutorial: Get started with gRPC in ASP.NET Core

  • gRPC services with ASP.NET Core

  • Migrating gRPC services from C-core to ASP.NET Core

总结

今天分享的内容有点多,目的就是使记录尽可能的详细,尽可能用通俗易懂的语言来进行描述,让大家能用起来。在asp.net core3.0中把grpc服务作为第一等公民进行支持,所以我们有必要进行下了解。可能很多朋友会有疑问了,我Web API用的爽歪歪,干嘛还要用gRPC这种远程过程调用协议啊。关于这个问题,我准备再单独开一篇文章进行讲解,最后感谢大家的阅读,码字不易,多多推荐支持吧!

640?wx_fmt=jpeg


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

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

相关文章

[ZJOI2010] 基站选址(线段树优化dp)

problem luogu-P2605 solution 首先&#xff0c;肯定都能想到最暴力的 dpdpdp。 dpi,j:idp_{i,j}:idpi,j​:i 个村庄为止一共选了 jjj 个基站&#xff0c;且第 iii 个村庄一定建立基站的最小费用。 通过我们的定义可知第 nnn 个村庄一定被选&#xff0c;实际上未必。 所以…

cf1553E. Permutation Shift

cf1553E. Permutation Shift 题意&#xff1a; 给出一个1到n的排列&#xff0c;每次可以交换两个数&#xff0c;问在交换最多m次(m < n/3)之后能不能得到由1 2 3 … n循环右移所得到的的排列&#xff0c;输出所有能得到的排列和循环右移的次数。 数据范围&#xff1a;n &l…

结合使用 Draft 与 Tencent Kubernetes Engine (TKE)

Draft 是一种开源工具&#xff0c;有助于在 Kubernetes 群集中打包和部署应用程序容器&#xff0c;让你专注于开发周期 - 专注开发的“内部循环”。 在开发代码期间&#xff0c;但尚未将代码提交到版本控制之前&#xff0c;Draft 将会运行。 借助 Draft&#xff0c;可在代码发生…

[ZJOI2010] 贪吃的老鼠(二分+差分+神仙建图网络流)

problem luogu-P2570 solution 卧槽网络流尼玛神题 首先这个最小延长时间 TTT &#xff0c;套路地考虑二分&#xff0c;将问题转化为判定性问题。 其次 n,mn,mn,m 和奶酪存在时间 [l,r][l,r][l,r] 的量级差很大&#xff0c;我们肯定会猜想一段时间内选择吃奶酪的老鼠是一样…

cf1553D. Backspace

cf1553D. Backspace 题意&#xff1a; 有一个字符串A,现在将其一个一个输入至B中,在输入一个字符时,如果按下backspace,那么这个字符不会被键入,而且如果B不为空,则前一位(B.back)也会被删除,现给出一个字符串C,问能否得到一个B&#xff0c;使得BC 题解&#xff1a; 为了通…

基于IdentityServer的系统对接微信公众号

业务需求公司有两个业务系统&#xff0c;A和B&#xff0c;AB用户之间属于多对一的关系&#xff0c;数据库里面也就是两张表&#xff0c;A表有个外键指向B。现在需要实现以下几个功能。A用户扫描B的二维码&#xff0c;填写相关的注册信息&#xff0c;注册完成之后自动属于B。也就…

[TJOI2012] 旅游(树的直径)

problem 写的什么jb题意&#xff01;这个语文水平。。。。 洛谷的一堆题解看下来也没懂他们懂得题目大意&#xff0c;真是给我蚌埠住了 luogu评测链接 一句话题意&#xff1a;给定一个三角剖分&#xff0c;求任意两顶点穿过的最多三角形个数&#xff08;只经过某三角形顶点…

Python知识(4/20):Python条件判断

任何一个复杂的系统都是由三种基本结构组成&#xff1a;顺序结构、分支结构、循环结构。其中 顺序结构最简单&#xff0c;程序从上到下依次执行&#xff0c;就如同生活中一条笔直的大马路&#xff0c;一路畅行无阻&#xff1b; 分支结构是指当程序执行到某步时&#xff0c;需根…

Ocelot Api网关教程(9)- QoS

本文介绍Ocelot中的QoS(Quality of Service)&#xff0c;其使用了Polly对超时等请求下游失败等情况进行熔断。1、添加Nuget包添加 Ocelot.Provider.Polly 到OcelotGetway项目中2、修改 Startup.ConfigureServices 如下来添加Polly&#xff1a;services .AddOcelot(new Confi…

cf1553F. Pairwise Modulo

cf1553F. Pairwise Modulo 题意&#xff1a; 给你一个数组a&#xff0c;a由n个不同的数组成,让你求出对应的数组p 数组p的定义为&#xff1a; pk∑1≤i,j≤kaimodajp_{k}\sum_{1\leq i,j\leq k}a_{i} \mod a_{j}pk​∑1≤i,j≤k​ai​modaj​ 题解&#xff1a; 官方题解 首…

[ZJOI2011]营救皮卡丘(费用流 + 最短路)

problem luogu-P4542 solution 刚开始就直观感觉 dpdpdp 不动&#xff0c;却有个看似“理所当然”的贪心&#xff1a;每次跑 kkk 个人所在点到扩展据点的最短距离&#xff0c;然后让最近的人去破环那个据点。 啪啪敲完后小样例&#xff08;实在太水&#xff09;就过了&…

Deltix Round, Spring 2021 (open for everyone, rated, Div. 1 + Div. 2)

Deltix Round, Spring 2021 (open for everyone, rated, Div. 1 Div. 2) 题号题目知识点AGame of LifeBLord of the ValuesCCompression and ExpansionDLove-HateECrypto LightsFFavorite GameGTry BookingHHopping Around the Array

Abp框架准备加入.NET Foundation

Abp团队正准备尝试将Abp项目加入.NET Foundation!既然申请了,必然有很大的自信能够成功,请大家等待好消息!Abp中文网会第一时间跟进.点击阅读原文查看最新进展.

[ZJOI2011] 道馆之战(树链剖分)

problem luogu-P4679 理解清楚题意又是一个世纪的更迭了 给定一个树&#xff0c;每个节点位置上实际放了两个节点。 然后若干次修改和查询。... 能走&#xff0c;#\## 不能走。 询问 u→vu\rightarrow vu→v 的简单路径上最长能走的距离。&#xff08;是强制从 uuu 开始&a…

[NOI2008] 志愿者招募(线性规划-对偶问题-费用流)

problem luogu-P3980 solution 志愿者连续工作 [si,ti][s_i,t_i][si​,ti​] 天&#xff0c;我们可以提炼出网络流二十四题中《最长k可重区间集问题》的模型。 同样地&#xff0c;把 1∼n1\sim n1∼n 天抽象成一条 1∼n11\sim n11∼n1 个点的链条。 源点 s→1s\rightarrow…

互达的集合(线段树)

problem 给定数组 l,rl,rl,r。求有多少个非空集合 SSS&#xff0c;满足 ∀i,j∈Sli≤j≤ri\forall_{i,j\in S}\ l_i\le j\le r_i∀i,j∈S​ li​≤j≤ri​。 集合内对于任意一个点而言&#xff0c;其余点均能被自己的范围覆盖到。 n≤2e5n\le 2e5n≤2e5。 solution 分享一下…

【学习笔记】线性规划与对偶问题和LP对偶费用流([ZJOI2013]防守战线题解)

线性规划与对偶问题 原问题&#xff1a; min⁡{7x1x25x3}s.t.{x1−x23x3≥105x12x2−x3≥6xi≥0\min\{7x_1x_25x_3\} \\ s.t.\begin{cases} x_1-x_23x_3\ge 10\\ 5x_12x_2-x_3\ge 6\\ x_i\ge 0\end{cases} min{7x1​x2​5x3​}s.t.⎩⎪⎨⎪⎧​x1​−x2​3x3​≥105x1​2x2​−…

【学习笔记】DAG / 一般有向图的支配树 / 灭绝树

定义与声明 一个有向图 GGG。给定一个起点 sss&#xff0c;假设 sss 能到达所有点。 若去掉某个点 iii 后&#xff0c;sss 无法到达 jjj&#xff0c;则称 iii 为 jjj 的支配点。 显然支配点存在传递关系。 以 sss 为根&#xff0c;使得对于任意节点 iii&#xff0c;其树上祖…

[ZJOI2014] 星系调查(树上差分 + 数学推式子)

problem luogu-P3340 题面写得那么长&#xff0c;其实说白了就是求一条直线&#xff0c;使得若干个点到这条直线的距离平方的和最小&#xff0c;求这个最小值。 solution 我超爱数学&#xff0c;数学就是我的命&#xff0c;我一天不学数学我就难受&#xff01; 假设拟合出…

[ZJOI2014] 璀璨光华(bfs建图 + dfs搜索)

problem luogu-P3342 solution 你感觉这道题没考什么&#xff0c;又感觉考了什么 通过样例以及题面&#xff0c;我们并未获取到『立方体每个小方块的编号是按一定规则命名』的信息。 也就是说&#xff0c;我们需要通过输入的每个小方块相邻的编号的信息来建出这个立方体的…