一、简介

简单解析一下gRPC,gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架。

特点:

  • 跨语言
  • 内容protobuf格式(比json体积小),网络传输快
  • 使用HTTP/2进行传输

适合高性能轻量的微服务,一般对外的接口用restful api,内部服务的调用用gRPC。gRPC是一个分布式服务框架,和以前的WebService,WCF类似。

二、创建gRPC服务端

1.创建gRPC项目

新建一个gRPC模板的项目

特别的地方就这里4点。

1.基于http2来通信。

2.proto协议文件,greet.proto是项目默认给我们的一个hello world的示例。它会根据协议自动生成需要的类。

3.服务类,Greeter.GreeterBase来自于2中的proto文件自动生成的类,生成的类在\obj\Debug\net6.0\Protos 目录下。

自动生成的类:

4.Program.cs添加了gRPC服务,和把GreeterService注册到管道中。

2.编写自己的服务

怎么样写自己的调用服务呢?

 1.创建proto文件

参照上面的示例创建自己的Proto文件

代码:

syntax = "proto3";

option csharp_namespace = "GrpcDemo.Service";

package order;

// 订单服务定义
service Order {
// 创建订单
rpc CreateOrder (CreateRequest) returns (CreateResult);
//查询订单
rpc QueryOrder (QueryRequest) returns (QueryResult);
} //创建订单请求参数
message CreateRequest {
string orderNo = 1;
string orderName=2;
double price=3;
} //创建订单返回结果
message CreateResult {
bool result = 1;
string message=2;
} //查询订单请求参数
message QueryRequest{
int id=1;
}
//查询订单返回结果
message QueryResult{
int id=1;
string orderNo=2;
string orderName=3;
double price=4;
}

生成一下就能看到对应的类已经生成了。

 2.实现定义的服务

创建OrderService.cs

 public class OrderService:Order.OrderBase
{
private readonly ILogger<GreeterService> _logger;
public OrderService(ILogger<GreeterService> logger)
{
_logger = logger;
}
/// <summary>
/// 创建订单
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<CreateResult> CreateOrder(CreateRequest request, ServerCallContext context)
{
//报存数据库 todo return Task.FromResult(new CreateResult
{
Result=true,
Message="订单创建成功"
});
}
/// <summary>
/// 查询订单
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<QueryResult> QueryOrder(QueryRequest request, ServerCallContext context)
{
//查询数据库 //todo return Task.FromResult(new QueryResult
{
OrderInfo=new OrderInfo
{
Id = request.Id,
OrderNo = DateTime.Now.ToString("yyyyMMddHHmmss"),
OrderName = "冰箱",
Price = 1288
}
});
}
}

继承的Order.OrderBase 是上面的proto文件生成的,然后实现了proto里面定义的两个服务。

然后在program.cs里面把服务注入管道。

到这里服务端就完成了,就可以启动服务端了。

浏览器访问不了,要通过gRPC客户端才能访问,下面就建一个gRPC客户端。

三、创建gRPC客户端

1.创建客户端项目

1.1、这里创建一个控制台程序。

1.2、然后添加Nuget包

Google.Protobuf
Grpc.Net.Client
Grpc.Tools
Grpc.Net.clientFactory

1.3、把服务端的proto文件拷贝过来

1.4、编辑项目文件,把proto里面的内容替换掉,默认是服务端的配置

  <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
<Protobuf Include="Protos\order.proto" GrpcServices="Client" />

生成的时候,客户端也生成了对应proto的类

2.grPC服务https的调用

因为服务端提供了http和https的端口,这里先调用https的

创建GrpcRequestTest.cs类

 /// <summary>
/// gRPC请求测试
/// </summary>
public class GrpcRequestTest
{
public void CreateOrder()
{
//常规使用,https
string url = "https://localhost:7246";
using(var channel=GrpcChannel.ForAddress(url))
{
var client = new Order.OrderClient(channel);
var reply = client.CreateOrder(new CreateRequest()
{
OrderNo = DateTime.Now.ToString("yyyMMddHHmmss"),
OrderName = "冰箱22款",
Price = 1688
}); Console.WriteLine($"结果:{reply.Result},message:{reply.Message}");
}
Console.ReadKey();
}
}

结果:

3.gRPC内网http调用

      public void CreateOrder()
{
//使用http
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
string url = "http://localhost:5246"; using(var channel=GrpcChannel.ForAddress(url))
{
var client = new Order.OrderClient(channel);
var reply = client.CreateOrder(new CreateRequest()
{
OrderNo = DateTime.Now.ToString("yyyMMddHHmmss"),
OrderName = "冰箱22款",
Price = 1688
}); Console.WriteLine($"结果:{reply.Result},message:{reply.Message}");
}
Console.ReadKey();
}

比起https,前面多了一行。结果:

4.IOC注入的方式调用gRPC

4.1、program.cs里面注入gRPCClient

// See https://aka.ms/new-console-template for more information
using GrpcDemo.Client;
using GrpcDemo.Service;
using Microsoft.Extensions.DependencyInjection; Console.WriteLine("Hello, World!"); IServiceCollection services = new ServiceCollection();
services.AddTransient<GrpcRequestTest>(); #region gRPC Client注册
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
services.AddGrpcClient<Order.OrderClient>(options =>
{
options.Address = new Uri("http://localhost:5246");
}).ConfigureChannel(grpcOptions =>
{
//可以完成各种配置,比如token
});
#endregion //构建容器
IServiceProvider serviceProvider = services.BuildServiceProvider();
//解析grpc请求测试
var grpcRequestTest = serviceProvider.GetService<GrpcRequestTest>();
//执行
grpcRequestTest.CreateOrder();

grpcRequestTest里代码:

/// <summary>
/// gRPC请求测试
/// </summary>
public class GrpcRequestTest
{
private Order.OrderClient _orderClient;
public GrpcRequestTest(Order.OrderClient orderClient)
{
_orderClient = orderClient;
}
public void CreateOrder()
{
var reply = _orderClient.CreateOrder(new CreateRequest()
{
OrderNo = DateTime.Now.ToString("yyyMMddHHmmss"),
OrderName = "冰箱22款",
Price = 1688
});
Console.WriteLine($"结果:{reply.Result},message:{reply.Message}");
Console.ReadKey();
}
}

结果:

四、webapi中加入gRPC

通常我们的服务有对外提供对外接口,又要对内提供gRPC服务,那怎么做呢,下面在webapi中加入gRPC服务

1.创建asp.net core mvc项目

2.安装nuget包

Grpc.AspNetCore

3.添加protebuf文件

把上面的proto文件复制过来

4.添加Service

  public class OrderService : Order.OrderBase
{
private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger)
{
_logger = logger;
}
/// <summary>
/// 创建订单
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<CreateResult> CreateOrder(CreateRequest request, ServerCallContext context)
{
//报存数据库 todo return Task.FromResult(new CreateResult
{
Result = true,
Message = "订单创建成功"
});
}
/// <summary>
/// 查询订单
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<QueryResult> QueryOrder(QueryRequest request, ServerCallContext context)
{
//查询数据库 //todo return Task.FromResult(new QueryResult
{
OrderInfo = new OrderInfo
{
Id = request.Id,
OrderNo = DateTime.Now.ToString("yyyyMMddHHmmss"),
OrderName = "冰箱",
Price = 1288
}
});
}
}

5.注册gRPC服务

在Program.cs文件中

到这里,就把gRPC加入到webapi里面了。

6.验证

启动asp.net core mvc程序

浏览器能访问,证明 restful api是没问题的。

然后再用上面的客户端访问一下gRPC的服务。

结果:

这样就成功对外提供api接口和对内提供gRPC服务了。

源码地址:https://github.com/weixiaolong325/GrpcDemo.Service

.NET Core(.NET6)中gRPC使用的更多相关文章

  1. .NET Core(.NET6)中gRPC注册到Consul

    一.简介 上一篇文章介绍了.NET Core 中使用gRPC,在微服务中,我们通常要把服务做成服务注册,服务发现的方式,那么这里来说一下gRPC是如何注册到Consul中的. Consul的安装这里就 ...

  2. .Net Core(.NET6)中接入Log4net和NLog进行日志记录

    一.接入Log4net 1.按日期和大小混合分割日志 nuget包安装 log4net Microsoft.Extensions.Logging.Log4Net.AspNetCore 配置文件 配置文 ...

  3. .net core中Grpc使用报错:The remote certificate is invalid according to the validation procedure.

    因为Grpc采用HTTP/2作为通信协议,默认采用LTS/SSL加密方式传输,比如使用.net core启动一个服务端(被调用方)时: public static IHostBuilder Creat ...

  4. .net core中Grpc使用报错:The response ended prematurely.

    当我们调用Grpc是出现下面的一堆异常时,一般是由于LTS导致的: Call failed with gRPC error status. Status code: 'Unavailable', Me ...

  5. ASP.NET Core 3.0 gRPC 双向流

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 认证授权 一.前言 在前一文 <ASP.NE ...

  6. ASP.NET Core 3.0 gRPC 拦截器

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 拦截器 一. 前言 前面两篇文章给大家介绍了使用g ...

  7. ASP.NET Core 3.0 gRPC 身份认证和授权

    一.开头聊骚 本文算是对于 ASP.NET Core 3.0 gRPC 研究性学习的最后一篇了,以后在实际使用中,可能会发一些经验之文.本文主要讲 ASP.NET Core 本身的认证授权和gRPC接 ...

  8. 「译」 .NET 6 中 gRPC 的新功能

    gRPC是一个现代的.跨平台的.高性能的 RPC 框架.gRPC for .NET 构建在 ASP.NET Core 之上,是我们推荐的在 .NET 中构建 RPC 服务的方法. .NET 6 进一步 ...

  9. 通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[下]:管道是如何构建起来的?

    在<中篇>中,我们对管道的构成以及它对请求的处理流程进行了详细介绍,接下来我们需要了解的是这样一个管道是如何被构建起来的.总的来说,管道由一个服务器和一个HttpApplication构成 ...

随机推荐

  1. TCP/IP协议 | TCP协议 | UDP协议 | 三次握手四次挥手

    TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP.SMTP.TCP.UDP.IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP ...

  2. 数据库篇:mysql锁详解

    前言 sql事务的执行,如果需要锁定数据进行更新操作,则必定离不开锁 共享锁和排他锁 表锁 行锁 Record Lock 间隙锁 Gap Lock 行锁+间隙锁 Next-Key Lock 加锁场景( ...

  3. python django对数据表的增删改查操作

    新增操作:方式1:book = BookInfo(title='西游记',price=99)book.save() 方式2:BookInfo.objects.create(title='西游记',pr ...

  4. eureka自我保护机制是什么?

    当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式.

  5. spring 自动装配 bean 有哪些方式?

    Spring容器负责创建应用程序中的bean同时通过ID来协调这些对象之间的关系.作为开发人员,我们需要告诉Spring要创建哪些bean并且如何将其装配到一起. spring中bean装配有两种方式 ...

  6. 给定一个文件每一行是字符串,找出所有的逆序对,比如abc和cba是逆序的对

    1 #include<iostream> 2 #include<string> 3 #define MAX 100 4 using namespace std; 5 bool ...

  7. java接口返回为空时候如何处理

    java前后端分离以后,后端常常返回给前端以下的内容: 如果遇到某个字段的内容为空的时候会出现这样的情况: 图中红色箭头的情况是一个数组集合,但是该集合为空,所以就返回null,但是我们如果想对于这样 ...

  8. 常用缓存(cache)淘汰算法(LFU、LRU、ARC、FIFO、MRU)

    缓存算法是指令的一个明细表,用于决定缓存系统中哪些数据应该被删去. 常见类型包括LFU.LRU.ARC.FIFO.MRU. 最不经常使用算法(LFU): 这个缓存算法使用一个计数器来记录条目被访问的频 ...

  9. Python中查看变量的类型,内存地址,所占字节的大小

    查看变量的类型 #利用内置type()函数 >>> nfc=["Packers","49"] >>> afc=[" ...

  10. vim recording的使用方法

    使用vim时无意间触碰到q键,左下角出现"recording"这个标识,觉得好奇,遂在网上查了一下,然后这是vim的一个强大功能.他可以录 制一个宏(Macro),在开始记录后,会 ...