dotnet core 使用gRPC服务

 2021-8-24      dotnet   grpc 

什么是gRPC?

在聊聊什么是gRPC前,我们先来聊聊什么是RPC。

RPC,全称Remote Procedure Call,中文译为远程过程调用。通俗地讲,使用RPC进行通信,调用远程函数就像调用本地函数一样,RPC底层会做好数据的序列化与传输,从而能使我们更轻松地创建分布式应用和服务。

请求信息使用 Protobuf 进行对象序列化压缩(IDL)

而gRPC,则是RPC的一种,它是免费且开源的,由谷歌出品。使用gRPC,我们只需要定义好每个API的Request和Response,剩下的gRPC这个框架会帮我们自动搞定。

使用gRPC

一、gRPC服务端

引用NuGet包

Grpc.AspNetCore

Startup.csConfigureServices 函数配置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; }
    }
}

源码地址

https://gitee.com/raikay/demo/tree/master/Grpc/https

二、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

下载地址:

https://github.com/uw-labs/bloomrpc

点加号导入LuCat.proto

点TLS导入证书,我是在阿里云申请的免费证书

IMG

相关链接

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