(一) gRPC初探之协定优先方法进行 API 开发
介绍
gRPC 是由Google开发的一种与语言无关的高性能远程过程调用 (RPC) 框架,在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。对应的官方库已托管在GitHub上
优点:
- 现代高性能轻量级 RPC 框架。
- 协定优先 API开发,默认使用协议缓冲区,允许与语言无关的实现。
- 可用于多种语言的工具,以生成强类型服务器和客户端。
- 支持客户端、服务器和双向流式处理调用。
- 使用 Protobuf 二进制序列化减少对网络的使用。
gRPC 适用于:
- 效率至关重要的轻量级微服务。
- 需要多种语言用于开发的 Polyglot 系统。
- 需要处理流式处理请求或响应的点对点实时服务。
环境
- VS2019
- .Net Core SDK 3.1.403
创建C# gRPC服务
需要用到的包:
- Grpc.AspNetCore
定义*.proto文件
gRPC 使用协定优先方法进行 API 开发。 在 *.proto 文件中定义服务和消息。 proto具体配置详见
以下.proto 文件:
- 定义
GrpcService
服务 GrpcService
服务定义了CreateOrder
方法CreateOrder
发送CreateOrderInput
消息并接受CreateOrderOutPut
消息
syntax = "proto3";
option csharp_namespace = "GrpcService";
package GrpcService;
// The greeting service definition.
service OrderGrpc {
// Sends a greeting
rpc CreateOrder(CreateOrderInput) returns (CreateOrderOutPut);
}
// The request message containing the user's name.
message CreateOrderInput {
int32 buyerId = 1;
string buyerName = 2;
int32 orderId = 3;
string orderName = 4;
}
// The response message containing the greetings.
message CreateOrderOutPut {
int32 buyerId = 1;
string buyerName = 2;
int32 orderId = 3;
string orderName = 4;
}
此时我们新建一个OrderService.cs
需要继承OrderGrpc.OrderGrpcBase
。需要注意的是OrderGrpc
是我们在proto
文件中定义的
Grpc Service{
//...
}
OrderGrpcBase
是c#工具生成的。默认情况下,生成的OrderGrpcBase
不需要执行任何操作,因为其定义的虚方法会将 UNIMPLEMENTED
错误返回到调用它的任何客户端,此处的虚方法就是我们在proto
文件中定义的rpc CreateOrder
的内容,c#工具会帮我我们生成。我们需要创建OrderGrpcBase
的具体实现,所以有了上述我们需要新建一个OrderService.cs
类继承OrderGrpc.OrderGrpcBase
在Startup.cs
配置如下
public void ConfigureServices(IServiceCollection services)
{
//关键代码
services.AddGrpc();
//关键代码
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
//关键代码
endpoints.MapGrpcService<OrderService>();//添加到路由管道
//关键代码
});
}
使用C# 调用gRPC服务
需要用到的包:
- Google.Protobuf 其中包含 .NET Core 客户端
- Grpc.Net.Client 包含适用于 C# 的 Protobuf 消息
- Grpc.Tools 包含适用于 Protobuf 文件的 C# 工具支持
创建 dotnetcore 的控制台应用程序,引用上述的包
添加*.proto
- 将
order.proto
文件中的命名空间更新为项目的命名空间
- 编辑项目文件
客户端Program.cs
代码如下:
using Grpc.Net.Client;
using GrpcOrderClient;
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
// The port number(5001) must match the port of the gRPC server.
#region .NET Core 客户端必须在服务器地址中使用 https 才能使用安全连接进行调用:
//var channel = GrpcChannel.ForAddress("https://localhost:5001");
#endregion;
#region 使用不受信任/无效证书调用 gRPC 服务
//https://docs.microsoft.com/zh-cn/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0#call-insecure-grpc-services-with-net-core-client
var httpHandler = new HttpClientHandler();
httpHandler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = httpHandler });
#endregion
var client = new OrderGrpc.OrderGrpcClient(channel);
var result = await client.CreateOrderAsync(new CreateOrderInput
{
BuyerId = 1,
BuyerName = "张小三",
OrderId = 1,
OrderName = "方便面",
});
Console.WriteLine("Order: " + result);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
控制台输出:
以上一个简单基于proto
协定优先的grpc服务搭建完成,如果想深入学习参见微软官方文档即可
示例已上传到本人github