.NET gRPC核心功能初体验
gRPC是高性能的RPC框架, 有效地用于服务通信(不管是数据中心内部还是跨数据中心)。
由Google开源,目前是一个Cloud Native Computing Foundation(CNCF)孵化项目。
其功能包括:
•双向流•强大的二进制序列化•可插拔的身份验证,负载平衡和运行状况检查
在gRPC中,客户端应用程序可以直接在A服务器上调用B服务器的方法,就好像它是本地对象一样,从而使您更轻松地创建分布式应用程序和微服务。
与许多RPC系统一样,gRPC也是围绕着定义服务的思想(定义可远程调用方法的入参和返回值类型)。
在服务端,服务端实现此接口并运行gRPC服务器,以处理客户端调用。
在客户端,客户端有一个存根,提供与服务器相同的方法。
在本文中,我将向您展示如何使用.NET5创建gRPC服务。我将分解gRPC的一些重要基础概念,并给出一个有意思的包罗核心功能的实例。
1.创建一个gRPC服务器
我们从gRPC服务模板
创建一个新的dotnet项目。
如果使用Visual Studio,请创建一个新项目,然后选择gRPC Service模板,使用GrpcAuthor作为项目的名称。
1.1 定义Rpc 服务
客户端与服务端使用protocol buffers
交流/通信:
protocol buffers
既用作服务的接口定义语言(IDL),又用作底层消息交换格式。
① 使用
protocol buffers
在.proto文件中定义服务接口。在其中,定义可远程调用的方法的入参和返回值类型,服务端实现此接口并运行gRPC服务器以处理客户端调用。
② 定义服务后,使用protocol buffers编译器protoc
从.proto文件生成数据访问/传输类,该文件包含服务接口中消息和方法的实现。
关注VS脚手架项目Protos文件夹中的greet.proto。
syntax = "proto3";
option csharp_namespace = "GrpcAuthor";
package greet;
// The greeting service definition.
service Greeter {// Sends a greetingrpc 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;
}
从.proto文件内容上大致知道服务功能 (给某人一个回应), 这里提示一些语法:
①syntax
指示使用的protocol buffers的版本。在这种情况下,proto3是撰写本文时的最新版本。②csharp_namespace
指示生成的文件所在的命名空间
。package
说明符也是这个作用,用于防止协议消息类型之间的名称冲突。
对于C#,如果提供选项csharp_namespace,csharp_namespace值将用作命名空间;
在Java中,如果提供选项java_package,java_package将用作包名称。
③service Greeter定义服务基类名称, rpc SayHello (HelloRequest) returns (HelloReply); 是一个一元rpc调用 ④HelloRequest
和HelloReply
是在客户端和服务器之间交换信息的数据结构。它们被称为消息
。
你在消息字段中定义的数字是不可重复的,当消息被序列化为Protobuf
时,该数字用于标识字段,这是因为序列化一个数字比序列化整个字段名称要快。
1.2 实现服务接口
为了从.proto文件生成代码,可以使用protoc
编译器和C#插件来生成服务器或客户端代码。
脚手架项目使用Grpc.AspNetCore
NuGet包:所需的类由构建过程自动生成, 你只需要在项目.csproj文件中添加配置节:
<ItemGroup><Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
生成的代码知道如何使用protocol buffers与其他服务/客户端进行通信。
C#工具生成GreeterBase类型,将用作实现gRPC服务的基类。
public class GreeterService : Greeter.GreeterBase
{private readonly ILogger<GreeterService> _logger;public GreeterService(ILogger<GreeterService> logger){_logger = logger;}public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context){return Task.FromResult(new HelloReply{Message = "Hello " + request.Name});}
}
最后注册Grpc端点endpoints.MapGrpcService<GreeterService >();
--- 启动服务---...
2. 创建gRPC .NET控制台客户端
Visual Studio创建一个名为GrpcAuthorClient的新控制台项目。
安装如下nuget包:
Install-Package Grpc.Net.Client
Install-Package Google.Protobuf
Install-Package Grpc.Tools
Grpc.Net.Client
包含.NET Core客户端;
Google.Protobuf
包含protobuf消息API;
Grpc.Tools
对Protobuf文件进行编译。
①拷贝服务端项目中的.proto文件②将选项csharp_namespace值修改为GrpcAuthorClient。③更新.csproj文件的配置节
<ItemGroup><Protobuf Include="Protos\greet.proto" GrpcServices="Client" /></ItemGroup>
④Client主文件:
static void Main(string[] args)
{var serverAddress = "https://localhost:5001";using var channel = GrpcChannel.ForAddress(serverAddress);var client = new Greeter.GreeterClient(channel);var reply = client.SayHello(new HelloRequest { Name = "宋小宝!" });Console.WriteLine(reply.Message.ToString());Console.WriteLine("Press any key to exit...");Console.ReadKey();
}
使用服务器地址创建GrpcChannel,使用GrpcChannel对象实例化GreeterClient;
然后使用SayHello同步方法; 打印服务器响应结果。
3. 其他核心功能
3.1 通信方式
Unary RPC(一元Rpc调用): 上面的例子
Server streaming RPC :服务器流式RPC,客户端在其中向服务器发送请求,并读取消息流。客户端从返回的流中读取,直到没有更多消息为止。gRPC保证单个RPC调用中的消息顺序。
Client streaming RPC:客户端流式RPC,客户端使用流,写入一系列消息并发送到服务器。客户端写完消息后,它将等待服务器读取消息并返回响应。同样,gRPC保证了单个RPC调用中的消息顺序。
Bidirectional streaming RPC:双向流式通信,由于两个流是独立的,因此客户端和服务器可以按任何顺序读取和写入消息。例如,服务器可以等到收到客户端的所有消息后再写消息,或者服务器和客户端可以打“乒乓” (服务器收到请求,然后响应消息,然后客户端基于响应发送另一个消息,依此往返)
3.2 Metadata
元数据是以键值对列表的形式提供的有关特定RPC调用的信息(例如身份验证详细信息),其中键是字符串,值通常是字符串,但可以是二进制数据。元数据对于gRPC本身是不透明的:它允许客户端向服务器提供与调用相关的信息,反之亦然。
3.3 Channels
gRPC通道提供到指定主机和端口上的gRPC服务器的连接。
创建客户端存根时用到它,可以指定通道参数来修改gRPC的默认行为,例如打开或关闭消息压缩。
通道具有状态,包括已连接和空闲。
4. gRpc打乒乓球
针对脚手架项目,稍作修改--->乒乓球局
(考察gRpc双向流式通信、Timeout机制、异常处理):
客户端发送"gridsum", 服务端回发"musdirg"; 客户端再发送"gridsum", 往复......
① 添加接口
rpc PingPongHello(stream HelloRequest) returns (stream HelloReply);
② 实现服务契约
try
{while (!context.CancellationToken.IsCancellationRequested){var asyncRequests = requestStream.ReadAllAsync();// 客户端与服务端"打乒乓"await foreach (var req in asyncRequests){var send = Reverse(req.Name);await responseStream.WriteAsync(new HelloReply{Message = send,Id = req.Id +1});Debug.WriteLine($"第{req.Id}回合,服务端收到 {req.Name};开始第{req.Id + 1}回合,服务端回发 {send}");}}
}
catch(RpcException ex)
{System.Diagnostics.Debug.WriteLine($"{ex.Message}");
}
③ 客户端代码,控制乒乓球局在5s后终止
using (var cancellationTokenSource = new CancellationTokenSource( 5* 1000))
{try{var duplexMessage = client.PingPongHello(null, null, cancellationTokenSource.Token);await duplexMessage.RequestStream.WriteAsync(new HelloRequest { Id = 1, Name = "gridsum" }) ;var asyncResp = duplexMessage.ResponseStream.ReadAllAsync();await foreach (var resp in asyncResp){var send = Reverse(resp.Message);await duplexMessage.RequestStream.WriteAsync(new HelloRequest {Id= resp.Id, Name = send });Console.WriteLine($"第{resp.Id}回合,客户端收到 {resp.Message}, 客户端发送{send}");}}catch (RpcException ex){Console.WriteLine("打乒乓球时间到了(客户端5s后终断gRpc连接)");}}
https://github.com/zaozaoniao/GrpcAuthor
总结
gRPC是具有可插拔身份验证和负载平衡功能的高性能RPC框架。
使用protocol buffers定义结构化数据;使用不同语言自动产生的源代码在各种数据流中写入和读取结构化数据。
在本文中,您学习了如何使用protocol buffers 定义服务接口以及如何使用C#实现服务。最后,您使用gRPC双向流式通信创建了 "打乒乓球"Demo。
Additional Resources
• https://developers.google.com/protocol-buffers/docs/csharptutorial• https://www.grpc.io/docs/what-is-grpc/core-concepts/• https://docs.microsoft.com/en-us/dotnet/architecture/grpc-for-wcf-developers/why-grpc
.NET gRPC核心功能初体验相关推荐
- .NET WebSocket 核心原理初体验
上个月我写了<.NET gRPC核心功能初体验>, 里面使用gRPC双向流做了一个打乒乓球的Demo, [实时][双向]这两个标签是不是很熟悉,对, WebSockets也可以做实时双向通 ...
- ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)
早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...
- 声网一起 KTV 功能初体验 | 掘金技术征文
一起 KTV 是一个很重要,且能体现产品性能的功能,在学习声网 SDK 的时候,看到了一起 KTV 的 GitHub demo,并且官方也给出了相应的文档说明,在此也对我的学习过程做一个简单的记录. ...
- android 人生日历,人生日历Android版 功能初体验
千呼万唤始出来,人生日历终于发布手机Android版本了.下面跟随小编一起体验一下它的各个功能吧. 在手机屏幕上打开人生日历,进入程序之后,就会出现如下界面.进入界面简单美观,淡蓝色底色调,延续了人生 ...
- android 人生日历,人生日历Android版 安卓版人生日历功能初体验
千呼万唤始出来,人生日历终于发布手机Android版本了.下面跟随小编一起体验一下它的各个功能吧. 在手机屏幕上打开人生日历,进入程序之后,就会出现如下界面.进入界面简单美观,淡蓝色底色调,延续了人生 ...
- android 人生日历,人生日历Android版功能初体验
千呼万唤始出来,人生日历终于发布手机Android版本了.下面跟随小编一起体验一下它的各个功能吧. 在手机屏幕上打开人生日历,进入程序之后,就会出现如下界面.进入界面简单美观,淡蓝色底色调,延续了人生 ...
- win10云剪贴板 Android,Win10云剪贴板功能初体验
微软今日向Windows预览体验快速通道推送了Win10 17666预览版,该版本带来了期待已久的"云剪贴板"功能,MS酋长迫不及待地试用了一下,Windows10向云又迈近了一步 ...
- OCR - 微软windows 11系统自带的Windows OCR功能初体验
一.Power Automate简述 最近再了解一些ocr的相关信息,从一些网站上上看到微软的免费系统实用工具套件中包含ocr识别/pdf文本提取等. 什么是Power Automate? Windo ...
- java tls 实例_grpc加密TLS初体验(go、java版本)
grpc加密TLS初体验(go.java版本) grpc-go.java的安装编译helloworld可以参考如下文章 openssl的安装.生成秘钥证书可以参考如下文章 示例代码go版本 服务端代码 ...
最新文章
- 一起谈.NET技术,浅谈如何使用.NET存储XML数据
- 目标检测-基于Pytorch实现Yolov3(1)- 搭建模型
- Android之利用ColorMatrix进行图片的各种特效处理
- python学习之老男孩python全栈第九期_day002作业
- 一文搞定Linux shell脚本编程( 史上最全汇总 )
- android 标题栏进度圈使用方法,Android 自定义标题栏 显示网页加载进度的方法实例...
- 华为应用锁退出立即锁_华为P40系列三大安全锁,教你锁住你的隐私 - 企业资讯...
- html画布实现小球沿直线下落,[面向对象的案例]在canvas画布内实现小球的随机移动...
- C++难吗?好学吗?C++到底怎么样?
- js处理web页面滚动条
- SVN Description : The working copy is locked due to a previous error.
- python基础--字典
- memcpy( )函数复制二维数组 memcmp( )函数比较二维数组
- 激活Windows系统的方式
- 判断多边形的凹凸性和计算多边形面积:利用向量叉乘
- JTAG and Boundary Scan(zz)
- 厌倦了excel绘制地图的繁琐操作,来看看这款可视化地图神器!
- ICLR2020放榜 687篇入选34篇得满分!且看OpenReview数据图文详解
- 光纤收发器行业研究及十四五规划分析报告
- MySQL5.7免安装教程
热门文章
- python作业高级FTP(第八周)
- BZOJ 3231: [Sdoi2008]递归数列 (JZYZOJ 1353) 矩阵快速幂
- 【算法学习】网络流模板……
- 在应用程序中实现对NandFlash的操作
- workaround for %33 texture memory bug
- linkButton与Button 的click事件与onclientClick事件
- 百度新闻 谷歌新闻_每日新闻摘要:到目前为止,Google I / O提供的最佳信息
- Android风格ppt,Material Design风格的快手PPT
- Docker学习笔记
- Spring Data REST API集成Springfox、Swagger