文档 gRPC for .NET
文档 .NET 上的 gRPC 概述
gitHub gRPC for .NET

Protobuf

有关 Protobuf 消息的详细信息,请参阅 Protobuf 语言指南Protobuf学习

Kestrel

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/servers/?view=aspnetcore-6.0&tabs=windows#kestrel

什么是 gRPC?

gRPC 是一种新式的高性能框架,它发展了由来已久的远程过程调用协议。 从应用程序层面来看,gRPC 简化了客户端和后端服务之间的消息传递。 gRPC 源自 Google,是云原生产品服务的云原生计算基础 (CNCF) 生态系统的一部分,并且是开放源代码的。 CNCF 将 gRPC 视为培育中的项目。 培育意味着最终用户会在生产应用程序中使用该技术,该项目有大量的贡献者。
典型的 gRPC 客户端应用将公开实现业务操作的本地进程内函数。 在此之下,该本地函数会在远程计算机上调用另一个函数。 看起来是本地调用,实际上变成了对远程服务的透明进程外调用。 RPC 管道对计算机之间点到点网络通信、序列化和执行进行抽象化。
在云原生应用程序中,开发人员在工作中通常会处理不同的编程语言、框架和技术。 这种互操作性使消息协定和跨平台通信所需的管道变得复杂。 gRPC 提供“统一水平层”来对此类问题进行抽象化。 开发人员在本机平台中编写专注于业务功能的代码,而 gRPC 会处理通信管道。
gRPC 在最常用的开发堆栈(包括 Java、JavaScript、C#、Go、Swift 和 NodeJS)中提供全面的支持。

gRPC 的优势

gRPC 使用 HTTP/2 作为传输协议。 虽然与 HTTP 1.1 也能兼容,但 HTTP/2 具有许多高级功能:

  • 用于数据传输的二进制组帧协议 - 与 HTTP 1.1 不同,HTTP 1.1 是基于文本的。
  • 对通过同一连接发送多个并行请求的多路复用支持 - HTTP 1.1 将处理限制为一次处理一个请求/响应消息。
  • 双向全双工通信,用于同时发送客户端请求和服务器响应。
  • 内置流式处理,支持对大型数据集进行异步流式处理的请求和响应。
  • 减少网络使用率的标头压缩。

gRPC 是轻量型且高性能的。 其处理速度可以比 JSON 序列化快 8 倍,消息小 60% 到 80%。 在 Microsoft Windows Communication Foundation (WCF) 中,gRPC 的性能超过经过高度优化的 NetTCP 绑定的速度和效率。 与偏向于 Microsoft 堆栈的 NetTCP 不同,gRPC 是跨平台的。

gRPC 的应用场景

建议在以下场景中使用 gRPC:

  • 需要立即响应才能继续处理的同步后端微服务到微服务通信。
  • 需要支持混合编程平台的 Polyglot 环境。
  • 性能至关重要的低延迟和高吞吐量通信。
  • 点到点实时通信 - gRPC 无需轮询即可实时推送消息,并且能对双向流式处理提供出色的支持。
  • 网络受约束环境 - 二进制 gRPC 消息始终小于等效的基于文本的 JSON 消息。

在撰写本文时,gRPC 主要用于后端服务。 新式浏览器无法提供支持前端 gRPC 客户端所需的 HTTP/2 控制级别。 也就是说,支持使用 .NET 的 gRPC-Web,能够从使用 JavaScript 或 Blazor WebAssembly 技术构建的基于浏览器的应用进行 gRPC 通信。 gRPC-Web 使 ASP.NET Core gRPC 应用能支持浏览器应用中的 gRPC 功能:

  • 强类型、代码生成的客户端
  • 压缩 Protobuf 消息
  • 服务器流式处理

    协议缓冲区

    gRPC 采用名为协议缓冲区的开放源代码技术。 它们提供极为高效且不受平台影响的序列化格式,用于序列化服务相互发送的结构化消息。 开发人员使用跨平台接口定义语言 (IDL) 为每个微服务定义服务协定。 该协定作为基于文本的 .proto 文件实现,描述了每个服务的方法、输入和输出。 同一合同文件可用于基于不同开发平台构建的 gRPC 客户端和服务。
    Protobuf 编译器 protoc 使用 proto 文件为目标平台生成客户端和服务代码。 该代码包括以下组成部分:

  • 由客户端和服务共享的强类型对象,表示消息的服务操作和数据元素。

  • 一个强类型基类,具有远程 gRPC 服务可以继承和扩展的所需网络管道。
  • 一个客户端存根,其中包含调用远程 gRPC 服务所需的管道。

运行时,每条消息都序列化为标准 Protobuf 表示形式,并在客户端和远程服务之间交换。 与 JSON 或 XML 不同,Protobuf 消息被序列化为经过编译的二进制字节。
Microsoft 体系结构站点提供的适用于 WCF 开发人员的 gRPC 一书深入介绍 gRPC 和协议缓冲区。

先决条件

在 .NET Core 下使用 gRPC C# 时,只需安装 .NET Core
除此之外,您还可以将 gRPC C# 与这些运行时 / IDE 结合使用。

  • Windows: .NET Framework 4.5+, Visual Studio 2013 或更高版本, Visual Studio 代码
  • Linux: Mono 4+, Visual Studio Code
  • Mac OS X:单声道 4+、视觉工作室代码、适用于 Mac 的视觉工作室

    NET 中的 gRPC

    gRPC 集成到 .NET Core 3.0 SDK 及更高版本中。 以下工具对其提供支持:

  • 已安装 ASP.NET 和 Web 开发工作负载的 Visual Studio 2022

  • Visual Studio Code
  • dotnet CLI

    .NET gRPC示例(grpc-start)

    示例源代码
    在本教程中,你将了解:

  • 创建 gRPC 服务器。

  • 创建 gRPC 客户端。
  • 使用 gRPC Greeter 服务测试 gRPC 客户端。

.NET gRPC快速入门 - 图1
Visual Studio 2022 中的 gRPC 支持

创建 gRPC 服务

  • 启动 Visual Studio 2022 并选择“创建新项目”。
  • 在“创建新项目”对话框中,搜索 gRPC。 选择“ASP.NET Core gRPC 服务”,并选择“下一步” 。
  • 在“配置新项目”对话框中,为“项目名称”输入 GrpcGreeter。 将项目命名为“GrpcGreeter”非常重要,这样在复制和粘贴代码时命名空间就会匹配。
  • 选择“下一页”。
  • 在“其他信息”对话框中,选择“.NET 6.0 (长期支持)”,然后选择“创建”。

1663131741658.png

Program.cs

  1. using GrpcGreeter.Services;
  2. var builder = WebApplication.CreateBuilder(args);
  3. // 向容器添加Grpc服务.
  4. builder.Services.AddGrpc();
  5. var app = builder.Build();
  6. // 配置 HTTP 请求管道.
  7. app.MapGrpcService<GreeterService>();
  8. //默认路由入口
  9. app.MapGet("/", () => "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");
  10. app.Run();

appsettings.json

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Information",
  5. "Microsoft.AspNetCore": "Warning"
  6. }
  7. },
  8. "AllowedHosts": "*",
  9. "Kestrel": {
  10. "EndpointDefaults": {
  11. "Protocols": "Http2"
  12. }
  13. }
  14. }
  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Information",
  5. "Microsoft.AspNetCore": "Warning",
  6. "Microsoft.AspNetCore.Hosting": "Information",
  7. "Microsoft.AspNetCore.Routing.EndpointMiddleware": "Information"
  8. }
  9. }
  10. }

gRPC服务

  1. using Grpc.Core;
  2. using GrpcGreeter;
  3. namespace GrpcGreeter.Services
  4. {
  5. public class GreeterService : Greeter.GreeterBase
  6. {
  7. private readonly ILogger<GreeterService> _logger;
  8. public GreeterService(ILogger<GreeterService> logger)
  9. {
  10. _logger = logger;
  11. }
  12. public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
  13. {
  14. return Task.FromResult(new HelloReply
  15. {
  16. Message = "Hello " + request.Name
  17. });
  18. }
  19. }
  20. }
  1. syntax = "proto3";
  2. option csharp_namespace = "GrpcGreeter";
  3. package greet;
  4. // 问候服务定义
  5. service Greeter {
  6. // Sends a greeting
  7. rpc SayHello (HelloRequest) returns (HelloReply);
  8. }
  9. // 包含用户名的请求消息.
  10. message HelloRequest {
  11. string name = 1;
  12. }
  13. // 包含问候语的响应消息
  14. message HelloReply {
  15. string message = 1;
  16. }

运行服务

:::warning Visual Studio:

  • 启动 Kestrel 服务器。
  • 启动浏览器。
  • 导航到 http://localhost:port,如 http://localhost:7042。

    • 端口:随机分配给应用的端口号。
    • localhost:本地计算机的标准主机名。 Localhost 仅为来自本地计算机的 Web 请求提供服务。 :::
      1. info: Microsoft.Hosting.Lifetime[14]
      2. Now listening on: http://localhost:5193
      3. info: Microsoft.Hosting.Lifetime[14]
      4. Now listening on: https://localhost:7193
      5. info: Microsoft.Hosting.Lifetime[0]
      6. Application started. Press Ctrl+C to shut down.
      7. info: Microsoft.Hosting.Lifetime[0]
      8. Hosting environment: Development
      9. info: Microsoft.Hosting.Lifetime[0]
      10. Content root path: F:\project\LFC.NET.Demo.Project\Grpc.Service.Demo\GrpcGreeter\

      检查项目文件

      :::warning GrpcGreeter 项目文件:
  • Protos/greet.proto:定义 Greeter gRPC,并用于生成 gRPC 服务器资产。

  • Services 文件夹:包含 Greeter 服务的实现。
  • appSettings.json:包含配置数据,如 Kestrel 使用的协议。 有关详细信息,请参阅 ASP.NET Core 中的配置
  • Program.cs,其中包含:

  • 打开 Visual Studio 的第二个实例并选择“创建新项目”。

  • 在“创建新项目”对话框中,选择“控制台应用程序”,然后选择“下一步” 。
  • 在“项目名称”文本框中,输入“GrpcGreeterClient”,然后选择“下一步” 。
  • 在“其他信息”对话框中,选择“.NET 6.0 (长期支持)”,然后选择“创建”。

    NuGet 包

    gRPC 客户端项目需要以下 NuGet 包:

  • Grpc.Net.Client,其中包含 .NET Core 客户端。

  • Google.Protobuf 包含适用于 C# 的 Protobuf 消息。
  • Grpc.Tools,其中包含适用于 Protobuf 文件的 C# 工具支持。 运行时不需要工具包,因此依赖项标记为 PrivateAssets=”All”。

    1. Install-Package Grpc.Net.Client
    2. Install-Package Google.Protobuf
    3. Install-Package Grpc.Tools

    添加 greet.proto

  • 在 gRPC 客户端项目中创建 Protos 文件夹。

  • 从 gRPC Greeter 服务将 Protos\greet.proto 文件复制到 gRPC 客户端项目中的 Protos 文件夹 。 ```protobuf syntax = “proto3”;

option csharp_namespace = “GrpcGreeter”;

package greet;

// 问候服务定义 service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply); }

// 包含用户名的请求消息. message HelloRequest { string name = 1; }

// 包含问候语的响应消息 message HelloReply { string message = 1; }

  1. - greet.proto 文件中的命名空间更新为项目的命名空间:
  2. ```csharp
  3. option csharp_namespace = "GrpcGreeterClient";
  • 编辑 GrpcGreeterClient.csproj 项目文件:

右键单击项目,并选择“编辑项目文件”。

  • 添加具有引用 greet.proto 文件的 元素的项组:

    1. <ItemGroup>
    2. <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
    3. </ItemGroup>

    1663139788071.png

    Program.cs

  • 使用以下代码更新 gRPC 客户端 Program.cs 文件。 ```csharp // See https://aka.ms/new-console-template for more information

using Grpc.Net.Client; using GrpcGreeterClient;

//实例化 GrpcChannel,使其包含用于创建到 gRPC 服务的连接的信息 using var channel = GrpcChannel.ForAddress(“https://localhost:7193“);

//使用不受信任/无效证书调用 gRPC 服务方式一 //var channel = GrpcChannel.ForAddress(“http://localhost:5193“);

////使用不受信任/无效证书调用 gRPC 服务方式二 //var httpHandler = new HttpClientHandler(); //httpHandler.ServerCertificateCustomValidationCallback = // HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; //using var channel = GrpcChannel.ForAddress(“https://localhost:7193",new GrpcChannelOptions { HttpHandler = httpHandler });

//使用 GrpcChannel 构造 Greeter 客户端 var client = new Greeter.GreeterClient(channel);

//Greeter 客户端会调用异步 SayHello 方法 var reply = await client.SayHelloAsync( new HelloRequest { Name = “longfuchu” });

//显示 SayHello 调用的结果 Console.WriteLine(“Greeting:” + reply.Message); Console.WriteLine(“请按下任意键退出”); Console.ReadKey(); ```

  • 在前面突出显示的代码中,将 localhost 端口号 7042 替换为在 GrpcGreeter 服务项目的 Properties/launchSettings.json 中指定的 HTTPS 端口号。

Program.cs 包含 gRPC 客户端的入口点和逻辑。
通过以下方式创建 Greeter 客户端:

  • 实例化 GrpcChannel,使其包含用于创建到 gRPC 服务的连接的信息。
  • 使用 GrpcChannel 构造 Greeter 客户端:

    测试 gRPC 客户端

  • 在 Greeter 服务中,按 Ctrl+F5 在不使用调试程序的情况下启动服务器。

  • 在 GrpcGreeterClient 项目中,按 Ctrl+F5 在不使用调试程序的情况下启动客户端。

1663143819043.png