Używanie gRPC w aplikacjach przeglądarkiUse gRPC in browser apps

Przez Kuba Kowalski-królaBy James Newton-King

Dowiedz się, jak skonfigurować istniejącą ASP.NET Core usługę gRPC, która ma być wywoływana z aplikacji przeglądarki, przy użyciu protokołu gRPC-Web .Learn how to configure an existing ASP.NET Core gRPC service to be callable from browser apps, using the gRPC-Web protocol. gRPC-Web umożliwia przeglądarce JavaScript i Blazor aplikacjom wywoływanie usług gRPC Services.gRPC-Web allows browser JavaScript and Blazor apps to call gRPC services. Nie można wywołać usługi gRPC protokołu HTTP/2 z poziomu aplikacji opartej na przeglądarce.It's not possible to call an HTTP/2 gRPC service from a browser-based app. usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web, a nie gRPC protokołu HTTP/2.gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC.

Aby uzyskać instrukcje dotyczące dodawania usługi gRPC do istniejącej aplikacji ASP.NET Core, zobacz Dodawanie usług gRPC do aplikacji ASP.NET Core.For instructions on adding a gRPC service to an existing ASP.NET Core app, see Add gRPC services to an ASP.NET Core app.

Instrukcje dotyczące tworzenia projektu gRPC można znaleźć w temacie Tworzenie klienta i serwera platformy .NET Core gRPC w ASP.NET Core .For instructions on creating a gRPC project, see Tworzenie klienta i serwera platformy .NET Core gRPC w ASP.NET Core.

gRPC — sieć Web w ASP.NET Core a wysłannikagRPC-Web in ASP.NET Core vs. Envoy

Dostępne są dwa sposoby dodawania usługi gRPC-Web do aplikacji ASP.NET Core:There are two choices for how to add gRPC-Web to an ASP.NET Core app:

  • Obsługa gRPC-Web i gRPC protokołu HTTP/2 w ASP.NET Core.Support gRPC-Web alongside gRPC HTTP/2 in ASP.NET Core. Ta opcja powoduje użycie oprogramowania pośredniczącego dostarczonego przez Grpc.AspNetCore.Web pakiet.This option uses middleware provided by the Grpc.AspNetCore.Web package.
  • Użyj funkcji gRPC-Web wysłannika serwera proxy , aby przetłumaczyć GRPC-Web na gRPC http/2.Use the Envoy proxy's gRPC-Web support to translate gRPC-Web to gRPC HTTP/2. Przetłumaczone wywołanie jest następnie przekazywane do aplikacji ASP.NET Core.The translated call is then forwarded onto the ASP.NET Core app.

Każde podejście ma pewne wady i zalety.There are pros and cons to each approach. Jeśli środowisko aplikacji korzysta już z wysłannika jako serwera proxy, warto również użyć wysłannika do zapewnienia obsługi gRPC-sieci Web.If an app's environment is already using Envoy as a proxy, it might make sense to also use Envoy to provide gRPC-Web support. W przypadku rozwiązania Basic for gRPC-Web, które wymaga tylko ASP.NET Core, Grpc.AspNetCore.Web to dobry wybór.For a basic solution for gRPC-Web that only requires ASP.NET Core, Grpc.AspNetCore.Web is a good choice.

Konfigurowanie gRPC-sieci Web w ASP.NET CoreConfigure gRPC-Web in ASP.NET Core

usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web, a nie gRPC protokołu HTTP/2.gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC. gRPC — sieć Web nie wymaga żadnych zmian w usługach.gRPC-Web does not require any changes to services. Jedyną modyfikacją jest konfiguracja uruchamiania.The only modification is startup configuration.

Aby włączyć usługę gRPC-Web za pomocą usługi gRPC ASP.NET Core:To enable gRPC-Web with an ASP.NET Core gRPC service:

  • Dodaj odwołanie do pakietu GRPC. AspNetCore. Web .Add a reference to the Grpc.AspNetCore.Web package.
  • Skonfiguruj aplikację do używania gRPC-Web, dodając UseGrpcWeb i EnableGrpcWeb do Startup.cs:Configure the app to use gRPC-Web by adding UseGrpcWeb and EnableGrpcWeb to 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();
    });
}

Powyższy kod ma następujące działanie:The preceding code:

  • Dodaje oprogramowanie pośredniczące gRPC-Web, UseGrpcWeb po stronie routingu i przed punktami końcowymi.Adds the gRPC-Web middleware, UseGrpcWeb, after routing and before endpoints.
  • Określa, że endpoints.MapGrpcService<GreeterService>() Metoda obsługuje gRPC-Web with EnableGrpcWeb .Specifies the endpoints.MapGrpcService<GreeterService>() method supports gRPC-Web with EnableGrpcWeb.

Alternatywnie można skonfigurować oprogramowanie pośredniczące gRPC-Web, tak aby wszystkie usługi obsługiwały usługę gRPC-Web domyślnie i EnableGrpcWeb nie są wymagane.Alternatively, the gRPC-Web middleware can be configured so all services support gRPC-Web by default and EnableGrpcWeb isn't required. Określ new GrpcWebOptions { DefaultEnabled = true } , kiedy zostanie dodane oprogramowanie pośredniczące.Specify new GrpcWebOptions { DefaultEnabled = true } when the middleware is added.

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>();
        });
    }
}

Uwaga

Występuje znany problem, który powoduje niepowodzenie gRPC-Web, gdy jest hostowany przez Http.sys w programie .NET Core 3. x.There is a known issue that causes gRPC-Web to fail when hosted by Http.sys in .NET Core 3.x.

Obejście problemu z gRPC-Web Work on Http.sys jest dostępny tutaj.A workaround to get gRPC-Web working on Http.sys is available here.

gRPC — Web i CORSgRPC-Web and CORS

Zabezpieczenia przeglądarki uniemożliwiają stronom sieci Web wykonywanie żądań do innej domeny niż ta, która była obsługiwana przez stronę sieci Web.Browser security prevents a web page from making requests to a different domain than the one that served the web page. To ograniczenie dotyczy tworzenia połączeń sieci Web gRPC z aplikacjami przeglądarki.This restriction applies to making gRPC-Web calls with browser apps. Na przykład aplikacja przeglądarki obsługiwana przez program https://www.contoso.com ma zablokowany dostęp do usług gRPC — sieci Web hostowanych w systemie https://services.contoso.com .For example, a browser app served by https://www.contoso.com is blocked from calling gRPC-Web services hosted on https://services.contoso.com. Aby osłabić to ograniczenie, można użyć funkcji udostępniania zasobów między źródłami (CORS).Cross Origin Resource Sharing (CORS) can be used to relax this restriction.

Aby zezwolić aplikacji przeglądarki na wykonywanie wywołań sieci Web między źródłami gRPC, skonfiguruj mechanizm CORS w ASP.NET Core.To allow a browser app to make cross-origin gRPC-Web calls, set up CORS in ASP.NET Core. Użyj wbudowanej obsługi mechanizmu CORS i Uwidocznij nagłówki specyficzne dla gRPC za pomocą WithExposedHeaders .Use the built-in CORS support, and expose gRPC-specific headers with WithExposedHeaders.

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");
    });
}

Powyższy kod ma następujące działanie:The preceding code:

  • Wywołania AddCors dodawania usług CORS i konfigurowania zasad CORS, które ujawniają nagłówki specyficzne dla gRPC.Calls AddCors to add CORS services and configures a CORS policy that exposes gRPC-specific headers.
  • Wywołuje UseCors Dodawanie oprogramowania CORS po stronie routingu i przed punktami końcowymi.Calls UseCors to add the CORS middleware after routing and before endpoints.
  • Określa, że endpoints.MapGrpcService<GreeterService>() Metoda obsługuje mechanizm CORS z RequiresCors .Specifies the endpoints.MapGrpcService<GreeterService>() method supports CORS with RequiresCors.

gRPC — sieć Web i przesyłanie strumieniowegRPC-Web and streaming

Tradycyjna gRPC za pośrednictwem protokołu HTTP/2 obsługuje przesyłanie strumieniowe we wszystkich kierunkach.Traditional gRPC over HTTP/2 supports streaming in all directions. gRPC-Web oferuje ograniczoną obsługę przesyłania strumieniowego:gRPC-Web offers limited support for streaming:

  • gRPC — klienci korzystający z przeglądarki sieci Web nie obsługują wywoływania przesyłania strumieniowego i dwukierunkowego przesyłania strumieniowego klienta.gRPC-Web browser clients don't support calling client streaming and bidirectional streaming methods.
  • ASP.NET Core usługi gRPC Services hostowane na Azure App Service i usługach IIS nie obsługują przesyłania strumieniowego dwukierunkowego.ASP.NET Core gRPC services hosted on Azure App Service and IIS don't support bidirectional streaming.

W przypadku korzystania z usługi gRPC-Web zalecamy użycie metod jednoargumentowych i metod przesyłania strumieniowego serwera.When using gRPC-Web, we only recommend the use of unary methods and server streaming methods.

Wywołaj gRPC-Web z przeglądarkiCall gRPC-Web from the browser

Aplikacje przeglądarki mogą używać gRPC-Web do wywoływania usług gRPC Services.Browser apps can use gRPC-Web to call gRPC services. Istnieją pewne wymagania i ograniczenia dotyczące wywoływania usług gRPC Services z usługą gRPC-Web w przeglądarce:There are some requirements and limitations when calling gRPC services with gRPC-Web from the browser:

  • Serwer musi być skonfigurowany do obsługi gRPC-Web.The server must have been configured to support gRPC-Web.
  • Wywołania przesyłania strumieniowego klientów i połączeń dwukierunkowych nie są obsługiwane.Client streaming and bidirectional streaming calls aren't supported. Przesyłanie strumieniowe serwera jest obsługiwane.Server streaming is supported.
  • Wywoływanie usług gRPC w innej domenie wymaga skonfigurowania CORS na serwerze.Calling gRPC services on a different domain requires CORS to be configured on the server.

JavaScript gRPC — klient sieci WebJavaScript gRPC-Web client

Istnieje skrypt JavaScript gRPC-Web Client.There is a JavaScript gRPC-Web client. Aby uzyskać instrukcje dotyczące korzystania z usługi gRPC-Web w języku JavaScript, zobacz pisanie kodu klienta JavaScript z gRPC-Web.For instructions on how to use gRPC-Web from JavaScript, see write JavaScript client code with gRPC-Web.

Konfigurowanie gRPC-sieci Web za pomocą klienta .NET gRPCConfigure gRPC-Web with the .NET gRPC client

Klienta .NET gRPC można skonfigurować w taki sposób, aby wykonywać wywołania gRPC-sieci Web.The .NET gRPC client can be configured to make gRPC-Web calls. Jest to przydatne w przypadku Blazor WebAssembly aplikacji, które są hostowane w przeglądarce i mają te same ograniczenia http związane z kodem JavaScript.This is useful for Blazor WebAssembly apps, which are hosted in the browser and have the same HTTP limitations of JavaScript code. Wywołanie gRPC-Web z klientem .NET jest takie samo jak http/2 gRPC.Calling gRPC-Web with a .NET client is the same as HTTP/2 gRPC. Jedyną modyfikacją jest sposób tworzenia kanału.The only modification is how the channel is created.

Aby użyć gRPC-Web:To use gRPC-Web:

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

var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });

Powyższy kod ma następujące działanie:The preceding code:

  • Konfiguruje kanał do korzystania z gRPC-sieci Web.Configures a channel to use gRPC-Web.
  • Tworzy klienta i wywołuje połączenie przy użyciu kanału.Creates a client and makes a call using the channel.

GrpcWebHandler dostępne są następujące opcje konfiguracji:GrpcWebHandler has the following configuration options:

  • InnerHandler: podstawowy, HttpMessageHandler który wysyła żądanie HTTP gRPC, na przykład HttpClientHandler .InnerHandler: The underlying HttpMessageHandler that makes the gRPC HTTP request, for example, HttpClientHandler.
  • GrpcWebMode: typ wyliczeniowy, który określa, czy żądanie HTTP gRPC Content-Type ma wartość application/grpc-web lub application/grpc-web-text .GrpcWebMode: An enumeration type that specifies whether the gRPC HTTP request Content-Type is application/grpc-web or application/grpc-web-text.
    • GrpcWebMode.GrpcWeb konfiguruje zawartość do wysłania bez kodowania.GrpcWebMode.GrpcWeb configures content to be sent without encoding. Wartość domyślna.Default value.
    • GrpcWebMode.GrpcWebText konfiguruje zawartość do kodowania base64.GrpcWebMode.GrpcWebText configures content to be base64 encoded. Wymagane dla wywołań przesyłania strumieniowego serwera w przeglądarkach.Required for server streaming calls in browsers.
  • HttpVersion: protokół http Version służący do ustawiania HttpRequestMessage. Version w źródłowym żądaniu HTTP gRPC.HttpVersion: HTTP protocol Version used to set HttpRequestMessage.Version on the underlying gRPC HTTP request. gRPC — sieć Web nie wymaga określonej wersji i nie przesłania jej domyślnie, chyba że zostanie określona.gRPC-Web doesn't require a specific version and doesn't override the default unless specified.

Ważne

Wygenerowane gRPC klienci mają metody synchronizacji i asynchroniczne do wywoływania metod jednoargumentowych.Generated gRPC clients have sync and async methods for calling unary methods. Na przykład SayHello jest synchronizowana i SayHelloAsync jest asynchroniczna.For example, SayHello is sync and SayHelloAsync is async. Wywołanie metody synchronizacji w Blazor WebAssembly aplikacji spowoduje, że aplikacja przestanie odpowiadać.Calling a sync method in a Blazor WebAssembly app will cause the app to become unresponsive. Metody asynchroniczne muszą być zawsze używane w programie Blazor WebAssembly .Async methods must always be used in Blazor WebAssembly.

Używanie fabryki klienta gRPC z usługą gRPC-WebUse gRPC client factory with gRPC-Web

Klienta .NET zgodnego z programem gRPC-Web można utworzyć przy użyciu integracji usługi gRPC z usługą HttpClientFactory.A gRPC-Web compatible .NET client can be created using gRPC's integration with HttpClientFactory.

Aby użyć gRPC-Web z fabryką klienta:To use gRPC-Web with client factory:

  • Dodaj odwołania do pakietu do pliku projektu dla następujących pakietów:Add package references to the project file for the following packages:
  • Zarejestruj klienta gRPC z iniekcją zależności (DI) przy użyciu uniwersalnej AddGrpcClient metody rozszerzania.Register a gRPC client with dependency injection (DI) using the generic AddGrpcClient extension method. W Blazor WebAssembly aplikacji usługi są zarejestrowane przy użyciu programu "di in" Program.cs .In a Blazor WebAssembly app, services are registered with DI in Program.cs.
  • Skonfiguruj GrpcWebHandler przy użyciu ConfigurePrimaryHttpMessageHandler metody rozszerzenia.Configure GrpcWebHandler using the ConfigurePrimaryHttpMessageHandler extension method.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>((services, options) =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler()));

Aby uzyskać więcej informacji, zobacz gRPC integrację klienta w programie .NET Core.For more information, see gRPC integrację klienta w programie .NET Core.

Dodatkowe zasobyAdditional resources