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。

 
Startup类 ConfigureServices方法中会添加services.AddGrpc();代码增加Grpc支持。 Configure方法内gRPC服务添加到了终结点路由中。
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添加如下包:

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 实战(一)的更多相关文章

  1. .Net Core gRPC 实战(二)

    概述 gRPC 客户端必须使用与服务相同的连接级别安全性.  如调用服务时通道和服务的连接级别安全性不一致,gRPC 客户端就会抛出错误. gRPC 配置使用HTTP gRPC 客户端传输层安全性 ( ...

  2. ASP.NET Core gRPC 入门全家桶

    一. 说明 本全家桶现在只包含了入门级别的资料,实战资料更新中. 二.官方文档 gRPC in Asp.Net Core :官方文档 gRPC 官网:点我跳转 三.入门全家桶 正片: ASP.NET ...

  3. java版gRPC实战之二:服务发布和调用

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  5. Asp.Net Core 项目实战之权限管理系统(0) 无中生有

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  6. Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  7. Asp.Net Core 项目实战之权限管理系统(2) 功能及实体设计

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  8. Asp.Net Core 项目实战之权限管理系统(3) 通过EntityFramework Core使用PostgreSQL

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  9. Asp.Net Core 项目实战之权限管理系统(5) 用户登录

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

随机推荐

  1. xss-labs全关教程

    0x01 Level 1 查看源码,可以看到接收了name参数,并直接嵌入到HTML页面中了 没有任何过滤,而且直接会当作代码执行. 0x02 Level 2 先传入<script>ale ...

  2. .NET 中的 Worker Service 入门介绍

    翻译自 Steve Gordon 2020年3月30日的文章 <WHAT ARE .NET WORKER SERVICES?> [1] 随着 .NET Core 3.0 的发布,ASP.N ...

  3. text-align: justify 文本对齐

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. tp5 composer phpexcel使用方法

    1.compser 安装phpexcel.在windows命令行下输入:进入网站根目录,compser phpoffice/phpexcel 2.页面引入两个类: use PHPExcel_IOFac ...

  5. hdu3714 水三分

    题意:       给你一些函数 y = ax^2 + bx + c,的a >= 0 的二次函数,x的范围是0--1000, 问你在这个范围内函数值最大的最小是多少,最大指的是对于某一个x最大的 ...

  6. PAT 乙级 -- 1009 -- 说反话

    题目简述 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出.       输入格式:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是 ...

  7. OWASP-ZAP扫描器的使用

    目录 OWASP-ZAP 更新 代理 目录扫描 主动扫描(Active  Scan) 扫描结果 生成报告 OWASP-ZAP OWASP Zed攻击代理(ZAP)是世界上最受欢迎的免费安全审计工具之一 ...

  8. Windows Pe 第三章 PE头文件-EX-相关编程-2(RVA_FOA转换)

    RVA-FOA之间转换 1.首先PE头加载到内存之后是和文件头内容一样的,就算是偏移不同,一个是磁盘扇区大小(400H)另一个是内存页大小(1000H),但是因为两个都是开头位置,所以相同. 2.看下 ...

  9. Element ui结合springboot的简单实战

    Eelment UI简单实战 前端开发 1 创建项目,导入element ui(略) 2 大致设计出想要的效果,如下 3 创建包 根据设计的大致模样在项目的components中创建对应的包,方便以后 ...

  10. [刷题] 104 Maximum Depth of Binary Tree

    要求 求一棵二叉树的最高深度 思路 递归地求左右子树的最高深度 实现 1 Definition for a binary tree node. 2 struct TreeNode { 3 int va ...