.Net Core gRPC 实战(一)
gRPC 是一种与语言无关的高性能远程过程调用 (RPC) 框架。
gRPC 的主要优点是:
- 现代高性能轻量级 RPC 框架。
- 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
- 可用于多种语言的工具,以生成强类型服务器和客户端。
- 支持客户端、服务器和双向流式处理调用。
- 使用 Protobuf 二进制序列化减少对网络的使用。
这些优点使 gRPC 适用于:
- 效率至关重要的轻量级微服务。
- 需要多种语言用于开发的 Polyglot 系统。
- 需要处理流式处理请求或响应的点对点实时服务。
https://github.com/grpc/grpc 提供了.Net的支持库。
.Net Core 创建gRPC服务
新建项目选择"gRPC 服务"

vs需要Visual Studio 2019 16.4 或更高版本。
或者在终端中通过命令行创建 dotnet new grpc -o XXX
相比普通的.Net 项目回多出Protos和Services两个文件夹。Protos文件夹放置.proto文件,Services文件夹放置根据proto文件生成的Service。
public void ConfigureServices(IServiceCollection services)
{
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)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} 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");
});
});
}
.Net Core 创建gRPC客户端
1.新建.Net Core项目
示例新建控制台应用(.NET Core),并通过Nuget添加如下包:
- Grpc.Net.Client,其中包含 .NET Core 客户端。
- Google.Protobuf 包含适用于 C# 的 Protobuf 消息。
- Grpc.Tools 包含适用于 Protobuf 文件的 C# 工具支持。
2.创建 Protos 文件夹
客户端项目创建Protos 文件夹,并将服务项目中的 Protos\greet.proto 文件复制到该文件夹
3.修改客户端proto 文件的命名空间
option csharp_namespace = "GrpcClient";
4.编辑项目文件(GrpcClient.csproj)
添加关于proto元素的项组
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
5.构建客户端项目生成proto文件对应的类
6.添加客户端调用服务代码
static async Task Main(string[] args)
{
// The port number(5001) must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
启动gRPC服务和客户端连接
Demo中gRPC服务和Client在一个项目中,可以解决方案右键属性设置多个项目启动或这通过dotnet命令启动
看到如下输出说明gRPC服务和Client正常

开启gRPC日志
gRPC服务开启日志
在Program文件中增加如下代码

gRPC客户端开始日志
在创建客户端通道时设置 GrpcChannelOptions.LoggerFactory 属性。对于ASP.NET Core项目可以通过依赖注入的方式注入ILoggerFactory类型,本例中为Client为控制台应用,通过使用 LoggerFactory.Create 创建新的 ILoggerFactory 实例的方式。

添加Microsoft.Extensions.Logging包和Microsoft.Extensions.Logging.Console包
再次启动项目会有如下输出

Streaming RPC(流式传输)
上面介绍得示例为Simple RPC,当接收和处理大量数据时会造成阻塞。为了处理大数据适应实时场景,则需要使用Streaming RPC。
Streaming RPC分三种形式:
- Server-side streaming RPC:服务器端流式 RPC
- Client-side streaming RPC:客户端流式 RPC
- Bidirectional streaming RPC:双向流式 RPC
服务器流式处理方法
单向流,服务端为Stream,客户端为普通得RPC请求。服务器流式处理方法以参数的形式获取请求消息。方法返回时,服务器流式处理调用完成。
服务器流式处理方法启动后,客户端无法发送其他消息或数据。 对于连续流式处理方法,客户端可以主动将其取消,客户端将信号发送到服务器,并引发 ServerCallContext.CancellationToken。
服务器上通过异步方法使用 CancellationToken 标记,以实现以下目的:
- 所有异步工作都与流式处理调用一起取消。
- 该方法快速退出。
服务器流处理方法定义方式在返回值前添加stream关键字
rpc StreamingServer (HelloRequest) returns (stream HelloReply);
在service类里实现对应方法
public override async Task StreamingServer(HelloRequest request, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
while (!context.CancellationToken.IsCancellationRequested)
{
await responseStream.WriteAsync(new HelloReply() { Message= "Hello From "+ request.Name });
await Task.Delay(TimeSpan.FromSeconds(1), context.CancellationToken);
}
}
服务器流式处理方法,客户端在不再调用时需要主动将其取消。 客户端将信号发送到服务器,并引发 ServerCallContext.CancellationToken,从而取消服务。
客户端简单调用示例
var token = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using var replyStreamServer = client.StreamingServer(
new HelloRequest { Name = "StreamingServer" },
cancellationToken: token.Token);
try
{
await foreach (var item in replyStreamServer.ResponseStream.ReadAllAsync(token.Token))
{
Console.WriteLine(item.Message);
}
}
catch (RpcException exc)
{
Console.WriteLine(exc.Message);
}
客户端流式处理方法
单向流,客户端通过流式发起多次 RPC 请求给服务端,服务端发起一次响应给客户端。返回响应消息时,客户端流式处理调用完成。
客户端流处理方法定义在参数前增加stream关键字
rpc StreamingClient (stream HelloRequest) returns (HelloReply);
service里实现该方法
public override async Task<HelloReply> StreamingClient(IAsyncStreamReader<HelloRequest> requestStream, ServerCallContext context)
{
var replay = new HelloReply();
while (await requestStream.MoveNext())
{
replay.Count++;
replay.Message = "Hello From " + requestStream.Current.Name;
}
return replay;
}
通过requestStream.MoveNext()从客户端发送的流数据中读取消息。使用 C# 8 或更高版本,则可使用 await foreach 语法来读取消息。
await foreach (var message in requestStream.ReadAllAsync())
{
// ...
}
Client流形式发送数据示例代码
using var replyStreamClient = client.StreamingClient();
foreach (var name in new[] { "Stacking", "Client", "Stream" })
{
await replyStreamClient.RequestStream.WriteAsync(new HelloRequest
{
Name = name
});
}
await replyStreamClient.RequestStream.CompleteAsync();
var response = await replyStreamClient.ResponseAsync;
双向流式处理方法
双向流,客户端以流式的方式发起请求,服务端同样以流式的方式响应请求。
双向流定义在参数和返回值前都加上stream
rpc StreamingWays (stream HelloRequest) returns (stream HelloReply);
Service类实现方法
public override async Task StreamingWays(IAsyncStreamReader<HelloRequest> requestStream, IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{ while (await requestStream.MoveNext())
{
Console.WriteLine($"Begin read request");
Console.WriteLine(requestStream.Current.Name);
await responseStream.WriteAsync(new HelloReply() {
Message=DateTimeOffset.Now.ToString("HH:mm:ss")
});
} }
客户端调用代码
using var replyStreamWays = client.StreamingWays();
for (int i = 0; i < 5; i++)
{
await replyStreamWays.RequestStream.WriteAsync(new HelloRequest
{
Name = "StreamWaysName " + i,
});
} while (await replyStreamWays.ResponseStream.MoveNext())
{
try
{
Console.WriteLine($"Response Return:{replyStreamWays.ResponseStream.Current.Message}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
await replyStreamWays.RequestStream.CompleteAsync();
参考资料:
.Net Core gRPC 实战(一)的更多相关文章
- .Net Core gRPC 实战(二)
概述 gRPC 客户端必须使用与服务相同的连接级别安全性. 如调用服务时通道和服务的连接级别安全性不一致,gRPC 客户端就会抛出错误. gRPC 配置使用HTTP gRPC 客户端传输层安全性 ( ...
- ASP.NET Core gRPC 入门全家桶
一. 说明 本全家桶现在只包含了入门级别的资料,实战资料更新中. 二.官方文档 gRPC in Asp.Net Core :官方文档 gRPC 官网:点我跳转 三.入门全家桶 正片: ASP.NET ...
- java版gRPC实战之二:服务发布和调用
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- Asp.Net Core 项目实战之权限管理系统(0) 无中生有
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- Asp.Net Core 项目实战之权限管理系统(2) 功能及实体设计
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- Asp.Net Core 项目实战之权限管理系统(3) 通过EntityFramework Core使用PostgreSQL
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- Asp.Net Core 项目实战之权限管理系统(5) 用户登录
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
随机推荐
- 2021S软件工程——案例分析作业
2021S软件工程--案例分析作业 18231169 黄思为 项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任建) 这个作业的要求在哪里 案例分析作业 我在这个课程的目标是 了解并熟悉 ...
- 自动AC机qwq(大雾)以及trie图fail图的一些结论
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string&g ...
- Docker学习笔记---通俗易懂
目录 Docker 简介 Docker安装 Docker的基本组成 安装Docker 配置阿里云镜像加速 回顾helloworld流程 工作原理 Docker的常用命令 帮助命令 镜像命令 容器命令 ...
- 病毒木马查杀实战第010篇:QQ盗号木马之十六进制代码分析
前言 按照我的个人习惯,在运用诸如IDA Pro与OllyDBG对病毒进行逆向分析之前,我都会利用一些自动化的工具,通过静态或动态的分析方法(参见<病毒木马查杀第008篇:熊猫烧香之病毒查杀总结 ...
- hdu1305 字典树水题
题意: 给你一些字符串,然后问你他们中有没有一个串是另一个串的前缀. 思路: 字典树水题,(这种水题如果数据不大(这个题目不知道大不大,题目没说估计不大),hash下也行,把每个 ...
- 基于路由器的VRRP技术--VRRP的应用
目录 无Vlan的VRRP 有Vlan的VRRP 今天要讲的VRRP都是基于路由器的VRRP. 一:无Vlan的VRRP 如图,PC1和PC2是企业内网主机,AR1和AR2是企业访问外网的路由器,有一 ...
- Windows中的共享文件和文件服务器
目录 共享文件的设置 默认共享 关闭默认共享 关闭共享服务 共享文件夹权限 文件服务器资源管理器的搭建 文件共享是指主动地在网络上共享自己的计算机文件.一般文件共享使用P2P模式,文件本身存在用户本人 ...
- POJ1178枚举三个地方(所有点都去同一个点)
题意: 有一个国王和很多骑士,他们都要到某一个点去集合,然后问所有人都到达某个终点的距离和最小是多少?过程中如果国王遇到了一个骑士的话,国王就可以和骑士一起按照骑士的走法走,这是两个人算一 ...
- Java前后端分离的认识
1.原由 在网上查了关于前后端分离的资料,有所粗浅认识.记录下来,方便以后使用.以下均是个人看法,仅做参考.如有错误请指教,共同进步. 2.为什么前后端分离? ①.一个后台,可以让多种前台系统使用.后 ...
- 狂神说Elasticsearch7.X学习笔记整理
Elasticsearch概述 一.什么是Elasticsearch? Lucene简介 Lucene是一套用于全文检索和搜寻的开源程序库,由Apache软件基金会支持和提供 Lucene提供了一个简 ...