热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gRPC:在ASP.NETCore上的基本应用

gRPC是Google基于HTTP2和protobuf推出的一款也是当下热门的开源RPC(RemoteProcedureCall)框架。可在程序或者服务之间进行高性能低带宽的通信,

gRPC是Google基于HTTP/2和protobuf推出的一款也是当下热门的开源RPC(Remote Procedure Call)框架。可在程序或者服务之间进行高性能低带宽的通信,并且支持身份认证、日志系统等等需要用到的功能。在微服务作为主流的时代,各个服务之间的通信也是一个亟需解决的问题。在ASP.NET Core 3.x下,gRPC也是微软传统RPC框架WCF的有效替代。

使用gRPC,可以让客户端像调用本地方法一样地去调用服务端中的方法。gRPC是一种合约优先的API开发模式,就是我们需要先具体地定义好方法和参数后,再进行服务端功能开发和客户端调用。并且客户端和服务端可以是使用不同语言开发的程序,通过gRPC,一旦我们在自己的服务中定义了proto文件,任何其他gRPC支持的语言开发的程序都可以来调用这个通信,通信中涉及到的环境、序列化等gRPC都帮我们完成了。默认情况下,gRPC是使用Protocol Buffers作为其接口定义语言(Interface Definition Language),就是用来定义通信中要用的方法和参数。Protocol Buffers不依赖特定的语言,根据不同需求,编译器就可以将其转换生成C#、Java、Python、Go等十几种语言供我们开发使用,并且在通信中数据是序列化成二进制流的,从而获得更好的传输性能。

本文接下来简单介绍Protocol Buffers和gRPC在.NET Core中的基本用法,主要参考为官方文档和各位大佬的教程(文末有链接)。本文Demo已上传至☞GitHub。

那么先来简单介绍一下Protocol Buffers的语法。

○ 文件名后缀用 ".proto"
○ 别忘记在文首加上一句“syntax = "proto3",来指明使用的是proto3的语法(因为之前还有一个proto2)
○ 通过在proto文件中定义message类型来指明你想序列化传输的对象,可以类比成一个类其中包含你需要的多个字段。比如定义一个叫Person的message,其中包含3个字段。

1 message Person {
2   string name = 1;
3   int32 id = 2;
4   bool has_pOnycopter= 3;
5 }

○ 简单介绍下Protocol Buffer中常用的数据类型
  § 数值:double, float, int32, int64, uint32, uint64, sint32, sint64, fixed32, fixed64, sfixed32, sfixed64
  § 字符串:string
  § 布尔:bool
  § 字节:bytes ,最大长度232
  § 枚举:enum
    □ 定义枚举的方法,另外支持使用别名,别名是用不同的名称表示同一个枚举值,如下面的EnumAllowingAlias.STARTED和EnumAllowingAlias.RUNNING表示的是同一个枚举值。

1 enum EnumAllowingAlias {
2     option allow_alias = true;  //表示可以使用别名
3     UNKNOWN = 0;     //枚举的编号是从0开始的
4     STARTED = 1;
5     RUNNING = 1;
6 }

○ 定义message时,注意到每个字段都加了一个“唯一标识”的编号,这些编号用来在message转成二进制形式后标识具体字段是啥,在投入使用后尽可能避免修改字段的编号。编号范围是1~229-1其中编号1~15的字段使用一个字节来编码,编号16~2047则使用两个字节。所以将使用频率高的字段用1~15来编号,另外19000~19999是Protocol Buffers的保留字段,最好别用。
○ 字段的规则分为两种,singular(proto3中默认)和repeated,定义字段时二选一
  § singular
    大概是表示为单值,这个字段的值最多一个,与repeated相对
  § repeated
    大概像是集合类型,比如定义一个字段如“repeated string emails”大概意思可理解为List emails
○ 注释的写法和C#文件中注释的写法基本一致,用“//”或者“/* … */”
○ 保留字段。如果一个已投入使用的proto中移除了某些字段的话,而用户仍然使用这些字段编号就会造成一些较严重的错误。解决办法是将这些想移除的字段名或者字段编号使用reserved关键字修饰。使用了reserved标注的字段在未来使用时,protocol buffer编译器将会抛出错误。

1 message Foo {
2   reserved 2, 15, 9 to 11;
3   reserved "foo", "bar";
4 }

○ 当使用protocol buffer编译器将proto文件编译成C#语言,会自动生成.cs文件,其中为每个message编译成class。
○ 编译后的类型与C#中类型的对应关系

proto类型 double float int32 int64 string bool bytes enum
C#类型 double float int long string bool ByteString enum
默认值 0 0 0 0 string.Empty false 空字节数组 枚举中的第一个值

○ 定义完message后,可以将其打包供其他service或者message引用,那么在protocol buffer中打包和引用的方法也很简单
  § 打包语法:

package foo.bar;
message Open { ... } 

  § 指定生成自定义的C#命名空间的语法:

option csharp_namespace = "Foo.MyBar";

  § 引用其他proto文件中定义的message类型的语法:

import "myproject/other_protos.proto";

○ 有了message的定义,要在RPC中应用的话就需要定义“方法”,在protocol buffer中即是service。在.proto文件中定义service的语法是:

service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}

○ 其中service和rpc都是关键字,Search是“方法”名,SearchRequest与SearchResponse都是定义的message类型。
○ 定义好service后,proto编译器就会将service使用我们选择的语言编译成的服务接口的代码。
○ Protocol buffers的一些其他关键字如any,oneof等暂时没用上,就先不列出了,可参考官方文档。

gRPC Demo实践

IDE使用的VS2019,首先使用ASP.NET Core建立一个gRPC的服务端,使用一个WPF程序作为客户端实现最基本的gRPC通信Demo,以一个员工信息的增查为例来演示gRPC中的常用场景。
gRPC 通常有四种模式的通信,分别是“一元(unary)”,“客户端流(client streaming)”,“服务端流(server streaming)” 以及“双向流模式( bidirectional streaming)”,对于 HTTP 2 来说其实都是用流的模式,以下实验是参考杨旭大佬的教程。

首先创建gRPC服务端,新建一个空白的ASP.NET Core Web应用程序命名为gRPC.Server。用NuGet安装“Grpc.AspNetCore”。新建一个Protos文件夹来存放.proto文件,新建一个名为Message.proto的文件来定义通信过程中需要的message。

gRPC:在ASP.NET Core上的基本应用
 1 syntax = "proto3";    //给编译器指明语法为proto3
 2 
 3 //员工
 4 message Employee{
 5     int32 Id = 1;                //Id
 6     string Name = 2;                //姓名
 7     int32 EmployeeNo = 3;        //工号
 8     Gender Gender = 4;            //性别
 9     Date BirthDay = 5;            //生日
10     string Department = 6;        //部门
11     bool IsValid = 7;            //有效性
12     bytes Photo = 8;            //照片
13 }
14 //性别(枚举)
15 enum Gender{
16     NOT_SPESIFICED = 0;
17     FEMALE = 1;
18     MALE = 2;
19 }
20 //日期
21 message Date{
22     int32 Year = 1;
23     int32 MOnth= 2;
24     int32 Day = 3;
25 }
26 
27 //Service 用的参数:
28 //根据Id查询员工信息
29 message GetEmployeeByIdRequest{    
30     int32 Id = 1;
31 }
32 //上传的员工信息请求
33 message EmployeeRequest{
34     Employee Employee = 1;
35 }
36 //返回员工信息
37 message EmployeeResponse{
38     Employee Employee = 1;
39 }
40 //根据条件查询员工
41 message GetEmployeeCollectionRequest{
42     string SearchTerm = 1;
43     bool IsValid = 2;
44 }
45 //返回员工信息集合
46 message GetEmployeeCollectionReponse{
47     Employee Employee = 1;
48 }
49 //上传员工照片
50 message AddPhotoRequest{
51     bytes Photo = 1;
52 }
53 //上传员工照片响应
54 message AddPhotoReponse{
55     bool IsOK = 1;
56 }
message.proto
推荐阅读
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • 本文介绍了一种处理AJAX操作授权过期的全局方式,以解决Asp.net MVC中Session过期异常的问题。同时还介绍了基于WebImage的图片上传工具类。详细内容请参考链接:https://www.cnblogs.com/starluck/p/8284949.html ... [详细]
  • 2022年的风口:你看不起的行业,真的很挣钱!
    本文介绍了2022年的风口,探讨了一份稳定的副业收入对于普通人增加收入的重要性,以及如何抓住风口来实现赚钱的目标。文章指出,拼命工作并不一定能让人有钱,而是需要顺应时代的方向。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • Hadoop2.6.0 + 云centos +伪分布式只谈部署
    3.0.3玩不好,现将2.6.0tar.gz上传到usr,chmod-Rhadoop:hadophadoop-2.6.0,rm掉3.0.32.在etcp ... [详细]
author-avatar
莫乂乂_465
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有