• 在浏览器应用中使用 gRPC


     gRPC-Web 允许浏览器 JavaScript 和 Blazor 应用调用 gRPC 服务。 

    有两种方式可将 gRPC-Web 添加到 ASP.NET Core 应用中:

    • 在 ASP.NET Core 中同时支持 gRPC-Web 和 gRPC HTTP/2。 此选项会使用 Grpc.AspNetCore.Web 包提供的中间件。
    • 使用 Envoy 代理的 gRPC-Web 支持将 gRPC-Web 转换为 gRPC HTTP/2。 转换后的调用随后会转发给 ASP.NET Core 应用。

    每种方法既有优点,也有缺点。 如果应用的环境已将 Envoy 用作代理,则也可以使用 Envoy 提供 gRPC-Web 支持。 对于仅需要 ASP.NET Core 的 gRPC-Web 的基本解决方案,Grpc.AspNetCore.Web 是一个不错的选择。

    若要使用 ASP.NET Core gRPC 服务启用 gRPC-Web:

    • 添加对 Grpc.AspNetCore.Web 包的引用。
    • 配置应用以使用 gRPC-Web,方法是将 UseGrpcWeb 和 EnableGrpcWeb 添加到 Startup.cs:
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
    
        app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb();
        });
    }

    或者,可以配置 gRPC-Web 中间件,使所有服务在默认情况下都支持 gRPC-Web,而不需要 EnableGrpcWeb。 在添加中间件时指定 new GrpcWebOptions { DefaultEnabled = true }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
        }
    
        public void Configure(IApplicationBuilder app)
        {
            app.UseRouting();
    
            app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<GreeterService>();
            });
        }
    }

    gRPC-Web 和 CORS

    浏览器安全性可防止网页向不处理网页的域发送请求。 此限制适用于使用浏览器应用发出 gRPC-Web 调用。 例如,由 https://www.contoso.com 提供服务的浏览器应用对托管于 https://services.contoso.com 上的 gRPC-Web 服务的调用会被阻止。 跨域资源共享 (CORS) 可用于放宽此限制。

    若要允许浏览器应用进行跨域 gRPC-Web 调用,请在 ASP.NET Core 中设置 CORS。 使用内置 CORS 支持,并使用 WithExposedHeaders 公开特定于 gRPC 的标头。

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
    
        services.AddCors(o => o.AddPolicy("AllowAll", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader()
                   .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
        }));
    }
    
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
    
        app.UseGrpcWeb();
        app.UseCors();
    
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                                      .RequireCors("AllowAll");
        });
    }

    gRPC-Web 和流式处理

    HTTP/2 上的传统 gRPC 支持所有方向的流式处理。 gRPC-Web 对流式处理提供有限的支持:

    • gRPC-Web 浏览器客户端不支持调用客户端流式处理和双向流式处理方法。
    • 托管在 Azure 应用服务和 IIS 上的 ASP.NET Core gRPC 服务不支持双向流式处理。

    使用 gRPC 时,仅建议使用一元方法和服务器流式处理方法。

    使用 .NET gRPC 客户端配置 gRPC-Web

    可以将 .NET gRPC 客户端配置为发出 gRPC-Web 调用。 这对于托管在浏览器中且具有相同 JavaScript 代码 HTTP 限制的 Blazor WebAssembly 应用来说非常有用。 使用 .NET 客户端调用 gRPC-Web 与 HTTP/2 gRPC 相同。 唯一的修改是创建通道的方式。

    var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
        {
            HttpHandler = new GrpcWebHandler(new HttpClientHandler())
        });

    GrpcWebHandler 具有以下配置选项:

    • InnerHandler:发出 gRPC HTTP 请求的基础 HttpMessageHandler,例如 HttpClientHandler
    • GrpcWebMode:枚举类型,指定 gRPC HTTP 请求 Content-Type 是 application/grpc-web 还是 application/grpc-web-text
      • GrpcWebMode.GrpcWeb 配置不进行编码即发送的内容。 默认值。
      • GrpcWebMode.GrpcWebText 配置需进行 base64 编码的内容。 对于浏览器中的服务器流式处理调用是必需的。
    • HttpVersion:HTTP 协议 Version 用于在基础 gRPC HTTP 请求上设置 HttpRequestMessage.Version。 gRPC-Web 不需要特定版本,且除非指定,否则不会替代默认版本。

    生成的 gRPC 客户端具有用于调用一元方法的同步和异步方法。 例如,SayHello 是同步的,而 SayHelloAsync 是异步的。 在 Blazor WebAssembly 应用中调用同步方法将导致应用无响应。 必须始终在 Blazor WebAssembly 中使用异步方法。

    将 gRPC-Web 与 gRPC 客户端工厂一起使用

    可以使用 gRPC 与 HttpClientFactory 的集成来创建与 gRPC-Web 兼容的 .NET 客户端。

    builder.Services
        .AddGrpcClient<Greet.GreeterClient>((services, options) =>
        {
            options.Address = new Uri("https://localhost:5001");
        })
        .ConfigurePrimaryHttpMessageHandler(
            () => new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()));

    gRPC HTTP API

    gRPC HTTP API 是为 gRPC 服务创建 RESTful JSON API 的 ASP.NET Core 的实验性扩展。 配置 gRPC HTTP API 后,应用可以使用熟悉的 HTTP 概念调用 gRPC 服务:

    1. 将包引用添加到 Microsoft.AspNetCore.Grpc.HttpApi
    2. 使用 AddGrpcHttpApi 在 Startup.cs 中注册服务。
    3. 将 google/api/http.proto 和 google/api/annotations.proto 文件添加到你的项目。
    4. 用 HTTP 绑定和路由在 .proto 文件中注释 gRPC 方法:
    syntax = "proto3";
    
    import "google/api/annotations.proto";
    
    package greet;
    
    service Greeter {
      rpc SayHello (HelloRequest) returns (HelloReply) {
        option (google.api.http) = {
          get: "v1/greeter/{name}"
        };
      }
    }
    
    message HelloRequest {
      string name = 1;
    }
    
    message HelloReply {
      string message = 1;
    }

     gRPC HTTP API 将传入的 HTTP 请求映射到 gRPC 消息,然后将响应消息转换为 JSON。

    gRPC HTTP API 与 gRPC-Web

    gRPC HTTP API 和 gRPC-Web 都支持从浏览器调用 gRPC 服务。 但是,它们的操作方式是不同的:

    • gRPC-Web 允许浏览器应用通过 gRPC-Web 客户端和 Protobuf 从浏览器调用 gRPC 服务。 gRPC-Web 需要浏览器应用生成 gRPC 客户端,并且具有快速发送小型 Protobuf 消息的优点。
    • gRPC HTTP API 允许浏览器应用调用 gRPC 服务,就像它们是使用 JSON 的 RESTful API 一样。 浏览器应用不需要生成 gRPC 客户端或了解 gRPC 的任何信息。
    var name = nameInput.value;
    
    fetch("/v1/greeter/" + name).then(function (response) {
      response.json().then(function (data) {
        console.log("Result: " + data.message);
      });
    });

    grpc-gateway

    Grpc-gateway 是从 grpc 服务创建 RESTful JSON API 的另一种技术。 它使用相同的 .proto 注释将 HTTP 概念映射到 gRPC 服务。

    Grpc-gateway 和 gRPC HTTP API 最大的区别是 grpc-gateway 使用代码生成来创建反向代理服务器。 反向代理将 RESTful 调用转换为 gRPC,然后将它们发送到 gRPC 服务。

  • 相关阅读:
    jquery 获取select框选中的值示例一则
    jsp的三种自定义标签 写法示例
    通过 SQL Server 视图访问另一个数据库服务器表的方法
    [转]SQLServer跨服务器访问数据库(openrowset/opendatasource/openquery)
    JS 禁用和重新启用a标签的点击事件
    JS原生父子页面操作
    为什么我们有时不用配置java环境变量?
    Android -- ViewPager多页面滑动切换以及动画效果
    Android -- 程序启动画面 Splash
    apache 伪静态 .htaccess
  • 原文地址:https://www.cnblogs.com/yetsen/p/13762365.html
Copyright © 2020-2023  润新知