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包。

 

posted @ 2021-08-30 15:04  名字都被注册了  阅读(407)  评论(0编辑  收藏  举报