什么是gRPC?
在聊聊什么是gRPC前,我们先来聊聊什么是RPC。
RPC,全称Remote Procedure Call,中文译为远程过程调用。通俗地讲,使用RPC进行通信,调用远程函数就像调用本地函数一样,RPC底层会做好数据的序列化与传输,从而能使我们更轻松地创建分布式应用和服务。
请求信息使用 Protobuf 进行对象序列化压缩(IDL)
而gRPC,则是RPC的一种,它是免费且开源的,由谷歌出品。使用gRPC,我们只需要定义好每个API的Request和Response,剩下的gRPC这个框架会帮我们自动搞定。
使用gRPC
一、gRPC服务端
引用NuGet包
Grpc.AspNetCore
Startup.cs
中 ConfigureServices
函数配置gRPC
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
//配置grpc
services.AddGrpc();
}
Configure
函数映射服务grpc类
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//映射grpc服务类
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapGrpcService<GreeterService>();
endpoints.MapGrpcService<LuCatService>();
});
}
Program.cs
添加证书、设置监听端口
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
var certificate = new X509Certificate2("https/6069857_game.raikay.com.pfx", "aE14DALS");
webBuilder.UseKestrel(options =>
{
options.AddServerHeader = false;
options.Listen(IPAddress.Any, 443, listenOptions =>
{
listenOptions.UseHttps(certificate);
});
}).UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseUrls("https://*:443");
});
appsettings.json
配置http2
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
}
添加协议文件LuCat.proto
syntax = "proto3";
option csharp_namespace = "AspNetCoregRpcService";
import "google/protobuf/empty.proto";
package LuCat; //定义包名
//定义服务
service LuCat{
//定义吸猫方法
rpc SuckingCat(ParamRequest) returns(SuckingCatResult);
}
message SuckingCatResult{
string message=1;
}
message ParamRequest {
int32 id = 1;
}
实现服务
LuCat.LuCatBase
是根据 LuCat.proto
文件自动生成的
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using System.Linq;
namespace AspNetCoregRpcService
{
public class LuCatService : LuCat.LuCatBase
{
private static readonly List<Cat> Cats = new List<Cat>() {
new Cat { Id = 1, Name = "英短银渐层", Describe = "英短银渐层是由英国短毛猫与金吉拉猫繁育而来" },
new Cat { Id = 2, Name = "英短金渐层" ,Describe="英短金渐层是由英短蓝猫改良而来"},
new Cat { Id = 3, Name = "美短" ,Describe="美短身体强健、勇敢活泼。"}
};
private static readonly Random Rand = new Random(DateTime.Now.Millisecond);
public override Task<SuckingCatResult> SuckingCat(ParamRequest param, ServerCallContext context)
{
Cat cat = null;
if (Cats.Any(_ => _.Id == param.Id))
{
cat = Cats.FirstOrDefault(_ => _.Id == param.Id);
}
else
{
cat = Cats[Rand.Next(0, Cats.Count)];
}
return Task.FromResult(new SuckingCatResult()
{
Message = $"您获得一只{cat.Name},{cat.Describe}"
});
}
}
public class Cat
{
public int Id { set; get; }
public string Name { set; get; }
public string Describe { set; get; }
}
}
源码地址
二、gRPC客户端
添加LuCat.proto
文件
LuCat.LuCatClient()
添加 LuCat.proto
文件后自动生成,和服务端 LuCat.proto
文件一致
syntax = "proto3";
option csharp_namespace = "AspNetCoregRpcService";
import "google/protobuf/empty.proto";
package LuCat; //定义包名
//定义服务
service LuCat{
//定义方法
rpc SuckingCat(ParamRequest) returns(SuckingCatResult);
}
message SuckingCatResult{
string message=1;
}
message ParamRequest {
int32 id = 1;
}
调用服务
static async Task Main(string[] args)
{
var channel = GrpcChannel.ForAddress("https://game.raikay.com/");
var catClient = new LuCat.LuCatClient(channel);
var catReply = await catClient.SuckingCatAsync(new ParamRequest { Id=0});
Console.WriteLine(""+ catReply.Message);
Console.ReadKey();
}
三、调试
调试工具:BloomRPC
下载地址:
点加号导入LuCat.proto
点TLS导入证书,我是在阿里云申请的免费证书
相关链接:
https://gitee.com/raikay/demo/tree/master/Geek/37-GrpcServerDemo
https://github.com/protobuf-net/protobuf-net.Grpc
https://gitee.com/raikay/demo/tree/master/other/GrpcDemo