gRPC是什么
gRPC源自google,是一种新式的高性能远程过程调用(remote process call)框架,在应用程序级别,它简化了客户端和后端服务之间的消息传送。
gRPC功能
- 高性能,基于协议的API开发
- 支持客户端、服务器、全双工通信,流式处理
- 提供了最常见开发堆栈(包括 Java、JavaScript、c#、switch、Swift和NodeJS)的全面支持
gRPC是轻型且高性能的。与JSON序列化相比,与JSON 序列化相比,速度有提升。
gRPC缺点
- 需要HTTP2协议,可能现有许多应用程序仍然没有采用这个协议
Asp.net core项目中尝鲜
1、新建gRPC服务
打开vs2019,选择“gRPC service”,创建一个新的项目
然后设置项目名称,保存位置。
2、创建成功后,需要添加下面的nuget包
- Grpc. AspnetCore
- Google.Protobuf
- Grpc.Tools
3、创建proto文件夹,新增proto文件
默认已经创建了一个proto文件夹,里面包含了一个greet.proto文件。我现在新增一个新的文件,命名为“Employee.proto”。
添加代码,如下所示:
syntax = "proto3";
import "google/protobuf/empty.proto";
import "google/protobuf/Timestamp.proto";
option csharp_namespace = "Dlx.GrpcService.Protos";
service EmployeeService{
rpc GetAllEmployee(google.protobuf.Empty) returns (ResponseMessage);
}
message EmployeeModel{
google.protobuf.Timestamp dateTimeStamp = 1 ;
string name = 2;
string skill = 3;
string email = 4;
}
message ResponseMessage{
string message = 1;
bool success = 2;
repeated EmployeeModel employees = 3;
}
然后,需要告诉编译器,这个文件需要使用客户端或者服务器的类型进行处理。
右键单击这个文件,并更改“Build Action”和“gRPC Stub classes ”属性。
生成后,检查项目文件查看引用是否正确。
4、查看Employee.proto是否已经正确变异以及创建了响应的C#类
5、创建“GetEmployeeService”服务类,并继承自“EmployeeService.EmployeeServiceBase”。
添加“GetAllEmployee”方法,我们将从gRPC客户端调用它。
using Dlx.GrpcService.Protos;
using Dlx.GrpcService.Repositories;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace Dlx.GrpcService.Services
{
public class GetEmployeeService : EmployeeService.EmployeeServiceBase
{
private readonly ILogger _logger;
private readonly IEmployeeRepository _employeeResosiotory;
public GetEmployeeService(ILogger logger, IEmployeeRepository employeeRepository)
{
_logger = logger;
_employeeResosiotory = employeeRepository;
}
public override Task GetAllEmployee(Empty request,ServerCallContext context)
{
var result = _employeeResosiotory.GetAllEmployees();
return Task.FromResult(result);
}
}
}
这里面使用仓储模式,可以方便被Mock掉。
6、现在先Mock一个仓储类,实现“IEmployeeRepository”。
using Dlx.GrpcService.Protos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Dlx.GrpcService.Repositories
{
public interface IEmployeeRepository
{
ResponseMessage GetAllEmployees();
}
public class EmployeeTestRepository : IEmployeeRepository
{
public ResponseMessage GetAllEmployees()
{
var rng = new Random();
var employeesData = Enumerable.Range(1, 3).Select(index => new EmployeeModel
{
Email = $"test{rng.Next(-20, 66)}@test.com",
Name = $"test name {rng.Next(-20, 66)}",
Skill = $"test skill {rng.Next(-20, 66)}"
}).ToList();
return new ResponseMessage
{
Employees = { employeesData },
Success = true,
Message = "Success"
};
}
}
}
在Startup.cs中注册服务和实例
7、现在运行该项目并确保gRPC服务端应用程序正常运行。
gRPC服务端应用程序运行成功。客户端可以访问这些终结点了。
8、创建gRPC客户端
新增一个.net core控制台应用程序
通过nuget添加包:Grpc.Net.Client、Google.Protobuf、Grpc.Tools
添加客户端调用代码:
using Dlx.GrpcService.Protos;
using Google.Protobuf.WellKnownTypes;
using Grpc.Net.Client;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;
namespace Dlx.GrpcClient
{
class Program
{
static async Task Main(string[] args)
{
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new EmployeeService.EmployeeServiceClient(channel);
Empty request = new Empty();
var reply = client.GetAllEmployee(request);
Console.WriteLine($"GetAllEmployee服务返回数据:{ JsonConvert.SerializeObject(reply.Employees)}");
Console.ReadKey();
}
}
}
先启用服务端,再启用客户端。
客户端调用服务,返回成功。
源码已上传到gitee。https://gitee.com/dx1024/dotnet-core-grpc-sample