zoukankan      html  css  js  c++  java
  • 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="ProtosHelloTest.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包。

  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/weiBlog/p/15206012.html
Copyright © 2011-2022 走看看