Grpc系列(一):Net5使用Grpc


最近公司新項目選項覺得使用GRPC,因為之前沒怎么接觸過,所以覺得研究記錄一下使用過程,話不多說,我們第一步先在項目里配置一下。

 

新建 AspNetCoreGrpc Api項目,Nuget安裝 Grpc.AspNetCore 包,Startup類里添加gRPC services:

services.AddGrpc();

 

然后添加Protos文件夾和PB協議文件 HelloTest.proto:

 

syntax = "proto3";

option csharp_namespace = "AspNetCoregRpcService";

import "google/protobuf/empty.proto";

package HelloGrpcTest; //定義包名

//定義服務
//定義方法
service HelloTest{
    rpc SayHello(SayHelloRequest) returns(SayHelloResult);
}

message SayHelloRequest{
    string Name=1;
}


//定義返回值
message SayHelloResult{
    string message=1;
}

這里添加了一個名為HelloTest的服務和名為SayHello的方法,有一個入參並且有一個返回類SayHelloResult,

 

然后我們需要在csproj 項目文件里,包含對 proto 文件引用:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

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

  <ItemGroup>
    <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
  </ItemGroup>

</Project>

 

然后我們添加服務的實現,添加Services文件夾和HelloTestService.cs實現類:

using AspNetCoregRpcService;
using Grpc.Core;
using System.Threading.Tasks;

namespace AspNetCoreGrpc.Services
{
    public class HelloTestService: HelloTest.HelloTestBase
    {
        public override Task<SayHelloResult> SayHello(SayHelloRequest request, ServerCallContext context)
        {
            var result = new SayHelloResult { Message = $"Hi,My name is {request.Name}!" };

            return Task.FromResult(result);
        }
    }
}

 

接着我們需要在Startup.cs的Configure方法里配置Map:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<HelloTestService>();
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
                });
            });
        }

最后我們需要在appsettings.json配置使用HTTP2,因為GRPC使用HTTP2通信:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2" } }
}

到這里GRPC服務端我們已經寫好並且能夠測試使用了,但是在實際生產中我們要測試一個方法或者接口通常是在swagger直接調用的,那么是不是可以讓GRPC也支持swagger呢,這個也是可以的,但是我們需要了解到,swagger走的是HTTP調用,那就意味着我們需要對服務進行HTTP和GRPC兩種支持,所以這里的解決方案是監聽兩個端口,分別支持HTTP和GRPC,我們需要接着做一點改動:

Nuget引入Microsoft.AspNetCore.Grpc.HttpApi、Microsoft.AspNetCore.Grpc.Swagger包,需要勾選預覽版,還沒發正式版,並替換Startup.cs里的方法:

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpcHttpApi();

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "AspNetCoreGrpc.api", Version = "v1" });
            });

            services.AddGrpcSwagger();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSwagger();

            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "AspNetCoreGrpc v1"));

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<HelloTestService>();
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
                });
            });
        }

這里我們需要因為兩個google的PB協議文件,所以大家需要下載一下:

https://github.com/aspnet/AspLabs/blob/c1e59cacf7b9606650d6ec38e54fa3a82377f360/src/GrpcHttpApi/sample/Proto/google/api/http.proto

https://github.com/aspnet/AspLabs/blob/c1e59cacf7b9606650d6ec38e54fa3a82377f360/src/GrpcHttpApi/sample/Proto/google/api/annotations.proto

放到google/api文件夾下就可以:

 

 

 

同時我們需要修改我們的HelloTest.proto協議文件配置路由:

syntax = "proto3";

option csharp_namespace = "AspNetCoregRpcService";

import "google/api/annotations.proto";

package HelloGrpcTest; //定義包名

//定義服務
//定義方法
service HelloTest{
    rpc SayHello(SayHelloRequest) returns(SayHelloResult){
        option (google.api.http) = {
        post: "/SayHello"
        body: "*"
        };
    };
}

message SayHelloRequest{
    string Name=1;
}


//定義返回值
message SayHelloResult{
    string message=1;
}

最后也是最關鍵的一步,設置分別監聽HTTP1和HTTP2端口:

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Hosting;

namespace AspNetCoreGrpc
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        // Additional configuration is required to successfully run gRPC on macOS.
        // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseUrls().UseKestrel((host, options) =>
                    {
                        options.ListenAnyIP(50051, o => o.Protocols = HttpProtocols.Http2);
                        options.ListenAnyIP(8081, o => o.Protocols = HttpProtocols.Http1);
                    });

                    webBuilder.UseStartup<Startup>();
                });
    }
}

然后我們再改一下launchSettings.json指定8081端口就可以運行了:

{
  "profiles": {
    "AspNetCoreGrpc": {
      "commandName": "Project",
      "launchBrowser": false,
      "applicationUrl": "https://localhost:8081",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

啟動運行然后瀏覽器打到 http://localhost:8081/swagger/index.html 看下:

 

 

 

 

 

看起來沒問題了,那么客戶端該如何使用呢,只要把Protos文件拷貝到客戶端項目里就可以了,當然常用方法是發布Nuget包。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM