.NET Core 下使用 gRPC

gRPC 是一種與語言無關的高性能遠程過程調用 (RPC) 框架。

gRPC 的主要優點

  • 現代高性能輕量級 RPC 框架。
  • 協定優先 API 開發,默認使用協議緩衝區,允許與語言無關的實現。
  • 可用於多種語言的工具,以生成強類型服務器和客戶端。
  • 支持客戶端、服務器和雙向流式處理調用。
  • 使用 Protobuf 二進制序列化減少對網絡的使用。

這些優點使 gRPC 適用於

  • 效率至關重要的輕量級微服務。
  • 需要多種語言用於開發的 Polyglot 系統。
  • 需要處理流式處理請求或響應的點對點實時服務。

gRPC 現在可以非常簡單的在 .NET Core 和 ASP.NET Core 中使用,並且已經開源,它目前由微軟官方 ASP.NET 項目的人員進行維護,良好的接入 .NET Core 生態。

接下來演示如何使用 gRPC,要想使用 gRPC 需要 .NET Core 3.1或者以上的SDK支持。gRPC分服務端和客戶端,所以新建兩個項目,一個控制檯當作客戶端gRPC_ClientDemo,一個ASP.NET Core 項目當作服務端gRPC_ServerDemo

先將服務端搞定,添加Grpc.AspNetCore組件

Install-Package Grpc.AspNetCore

然後Startup.cs中添加services.AddGrpc()

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();
}

因爲 gRPC 是基於 HTTP/2 來通信的,所以需要在配置文件中添加Kestrel 啓用 HTTP/2 的配置。

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}

gRPC 與傳統的api是不同的,需要我們自己定義proto文件,gRPC 使用協定優先方法進行 API 開發。 默認情況下,協議緩衝區 (protobuf) 用作接口設計語言 (IDL)。 *.proto 文件包含:

  • gRPC 服務的定義。
  • 在客戶端與服務器之間發送的消息。

有關 protobuf 文件的語法的詳細信息,可以查看官方文檔 (protobuf)。

proto文件在實際開發中肯定會有多個存在,這裏有一個技巧就是將proto文件放在一個文件夾內,然後利用ProtobufLink關聯即可,這樣就只用維護一份proto文件即可。

同時微軟還幫我們提供了dotnet-grpc,.NET Core 全局工具,請運行以下命令:

dotnet tool install -g dotnet-grpc

dotnet-grpc 可以用於將 Protobuf 引用作爲 <Protobuf /> 項添加到 .csproj 文件:

<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />

具體用法可以查看文檔:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/dotnet-grpc

在解決訪問文件夾根目錄添加 Proto 文件夾,新建一個hello.protoproto文件,將其分別連接到兩個項目中。

現在來開始編寫hello.proto,添加一個SayHello方法。

syntax = "proto3";

package hello; //定義包名

// 定義服務
service HelloService {
    // 定義一個 SayHello 方法
    rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}

然後來實現這個服務,在服務端添加一個GreeterService.cs

using Grpc.Core;
using Hello;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace gRPC_ServerDemo.Services
{
    public class GreeterService : HelloService.HelloServiceBase
    {
        private readonly ILogger _logger;

        public GreeterService(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<GreeterService>();
        }

        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            _logger.LogInformation($"Sending hello to {request.Name}");

            return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
        }
    }
}

HelloService.HelloServiceBaseproto文件爲我們自動生成的類。

調用重載方法SayHello(),記錄了一條日誌然後返回客戶端傳進來的字段name。

在配置文件中將GreeterService服務添加到路由管道中

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/", async context =>
    {
        await context.Response.WriteAsync("Hello World!");
    });

    endpoints.MapGrpcService<GreeterService>();
});

支持我們服務端完成,啓動服務端拿到啓動地址,https://localhost:5001

現在去客戶端配置地址調用我們寫的服務,在開始之前需要在客戶端解決方案先引用下面幾個nuget包。

Install-Package Grpc.Net.Client
Install-Package Google.Protobuf
Install-Package Grpc.Tools
using Grpc.Net.Client;
using Hello;
using System;
using System.Threading.Tasks;

namespace gRPC_ClientDemo
{
    class Program
    {
        static async Task Main(string[] args)
        {
            using var channel = GrpcChannel.ForAddress("https://localhost:5001");

            var client = new HelloService.HelloServiceClient(channel);

            await UnaryCallExample(client);
        }

        private static async Task UnaryCallExample(HelloService.HelloServiceClient client)
        {
            var reply = await client.SayHelloAsync(new HelloRequest { Name = "阿星Plus" });

            Console.WriteLine("Greeting: " + reply.Message);
        }
    }
}

啓動服務端和客戶端看看效果,成功發送消息和獲取消息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章