(一) gRPC初探之协定优先方法进行 API 开发

介绍

gRPC 是由Google开发的一种与语言无关的高性能远程过程调用 (RPC) 框架,在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。对应的官方库已托管在GitHub上

image

优点:

  • 现代高性能轻量级 RPC 框架。
  • 协定优先 API开发,默认使用协议缓冲区,允许与语言无关的实现。
  • 可用于多种语言的工具,以生成强类型服务器和客户端。
  • 支持客户端、服务器和双向流式处理调用。
  • 使用 Protobuf 二进制序列化减少对网络的使用。

gRPC 适用于:

  • 效率至关重要的轻量级微服务。
  • 需要多种语言用于开发的 Polyglot 系统。
  • 需要处理流式处理请求或响应的点对点实时服务。

环境

  • VS2019
  • .Net Core SDK 3.1.403

创建C# gRPC服务

需要用到的包:

  • Grpc.AspNetCore

image

定义*.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

image

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文件中的命名空间更新为项目的命名空间

image

  • 编辑项目文件
    image

客户端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();
        }
    }

控制台输出:

image

以上一个简单基于proto协定优先的grpc服务搭建完成,如果想深入学习参见微软官方文档即可
示例已上传到本人github

posted @ 2021-04-02 16:10  无敌土豆  阅读(305)  评论(0编辑  收藏  举报