Udostępnij za pośrednictwem


gRPC-Web w aplikacjach gRPC ASP.NET Core

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.

Autor: James Newton-King

Dowiedz się, jak skonfigurować istniejącą usługę gRPC platformy ASP.NET Core do wywoływania z aplikacji przeglądarki przy użyciu protokołu gRPC-Web . Usługa gRPC-Web umożliwia wywoływanie usług gRPC za pomocą języka JavaScript i Blazor aplikacji przeglądarki. Nie można wywołać usługi HTTP/2 gRPC z poziomu aplikacji opartej na przeglądarce. Usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web wraz z protokołem 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.

Aby uzyskać instrukcje dotyczące tworzenia projektu gRPC, zobacz Create a .NET Core gRPC client and server in ASP.NET Core (Tworzenie klienta i serwera gRPC platformy .NET Core w programie ASP.NET Core).

ASP.NET Core gRPC-Web a Envoy

Istnieją dwie opcje dodawania biblioteki gRPC-Web do aplikacji ASP.NET Core:

  • Obsługa protokołu gRPC-Web wraz z protokołem HTTP/2 gRPC w ASP.NET Core. Ta opcja używa oprogramowania pośredniczącego dostarczonego Grpc.AspNetCore.Web przez pakiet.
  • Użyj obsługi gRPC-Web serwera proxy usługi Envoy, aby przetłumaczyć bibliotekę gRPC-Web na protokół HTTP/2 gRPC. Przetłumaczone wywołanie jest następnie przekazywane do aplikacji ASP.NET Core.

Istnieją zalety i wady dla każdego podejścia. Jeśli środowisko aplikacji używa już aplikacji Envoy jako serwera proxy, warto również użyć usługi Envoy do zapewnienia obsługi gRPC-Web. W przypadku podstawowego rozwiązania dla sieci Web gRPC,które wymaga tylko ASP.NET Core, Grpc.AspNetCore.Web jest dobrym wyborem.

Konfigurowanie usługi gRPC-Web na platformie ASP.NET Core

Usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web wraz z protokołem HTTP/2 gRPC. gRPC-Web nie wymaga żadnych zmian w usługach. Jedyną modyfikacją jest ustawienie oprogramowania pośredniczącego w programie Program.cs.

Aby włączyć usługę gRPC-Web za pomocą usługi gRPC platformy ASP.NET Core:

  • Dodaj odwołanie do Grpc.AspNetCore.Web pakietu.
  • Skonfiguruj aplikację tak, aby korzystała z biblioteki gRPC-Web, dodając UseGrpcWeb element i EnableGrpcWeb do polecenia Program.cs:
using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb();

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled and is callable from browser apps using the gRPC-Web protocol");

app.Run();

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

  • Dodaje oprogramowanie pośredniczące gRPC-Web , UseGrpcWebpo routingu i przed punktami końcowymi.
  • Określa, że endpoints.MapGrpcService<GreeterService>() metoda obsługuje gRPC-Web z EnableGrpcWeb.

Alternatywnie można skonfigurować oprogramowanie pośredniczące gRPC-Web tak, aby wszystkie usługi domyślnie obsługiwały usługę gRPC-Web i EnableGrpcWeb nie są wymagane. Określ new GrpcWebOptions { DefaultEnabled = true } , kiedy oprogramowanie pośredniczące jest dodawane.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "All gRPC service are supported by default in this example, and are callable from browser apps using the gRPC-Web protocol");

app.Run();

Uwaga

Istnieje znany problem, który powoduje niepowodzenie biblioteki gRPC-Web w przypadku hostowania przez HTTP.sys na platformie .NET Core 3.x.

Obejście problemu umożliwiającego działanie biblioteki gRPC-Web na HTTP.sys jest dostępne w środowisku eksperymentalnym Grpc-web i useHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web i CORS

Zabezpieczenia przeglądarki uniemożliwiają stronie internetowej wykonywanie żądań do innej domeny niż ta, która obsłużyła stronę internetową. To ograniczenie dotyczy wykonywania wywołań gRPC-Web z aplikacjami przeglądarki. Na przykład aplikacja przeglądarki obsługiwana przez https://www.contoso.com usługę jest zablokowana do wywoływania usług gRPC-Web hostowanych w systemie https://services.contoso.com. Udostępnianie zasobów między źródłami (CORS) może służyć do złagodzenia tego ograniczenia.

Aby umożliwić aplikacji przeglądarki wykonywanie wywołań gRPC-Web między źródłami, skonfiguruj mechanizm CORS w usłudze ASP.NET Core. Użyj wbudowanej obsługi mechanizmu CORS i uwidaczniaj nagłówki specyficzne dla biblioteki gRPC za pomocą polecenia WithExposedHeaders.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
    builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));

var app = builder.Build();

app.UseGrpcWeb();
app.UseCors();

app.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                    .RequireCors("AllowAll");

app.MapGet("/", () => "This gRPC service is gRPC-Web enabled, CORS enabled, and is callable from browser apps using the gRPC-Web protocol");

app.Run();

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

  • Wywołania AddCors umożliwiające dodanie usług CORS i skonfigurowanie zasad CORS, które uwidacznia nagłówki specyficzne dla protokołu gRPC.
  • Wywołania UseCors w celu dodania oprogramowania pośredniczącego CORS po konfiguracji routingu i przed konfiguracją punktów końcowych.
  • Określa, że endpoints.MapGrpcService<GreeterService>() metoda obsługuje mechanizm CORS z RequireCors.

gRPC-Web i przesyłanie strumieniowe

Tradycyjna funkcja gRPC za pośrednictwem protokołu HTTP/2 obsługuje przesyłanie strumieniowe klienta, serwera i dwukierunkowego przesyłania strumieniowego. GRPC-Web oferuje ograniczoną obsługę przesyłania strumieniowego:

  • Klienci przeglądarki gRPC-Web nie obsługują wywoływania metod przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego.
  • Klienci gRPC-Web platformy .NET nie obsługują wywoływania metod przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego za pośrednictwem protokołu HTTP/1.1.
  • ASP.NET Core usługi gRPC hostowane w usłudze aplikacja systemu Azure i usługach IIS nie obsługują dwukierunkowego przesyłania strumieniowego.

W przypadku korzystania z gRPC-Web zalecamy używanie tylko metod jednoargumentowych i metod przesyłania strumieniowego serwera.

Protokół HTTP

Szablon usługi gRPC platformy ASP.NET Core dołączony do zestawu SDK platformy .NET tworzy aplikację skonfigurowaną tylko dla protokołu HTTP/2. Jest to dobra wartość domyślna, gdy aplikacja obsługuje tylko tradycyjne gRPC za pośrednictwem protokołu HTTP/2. GRPC-Web działa jednak zarówno z protokołem HTTP/1.1, jak i http/2. Niektóre platformy, takie jak platforma UWP lub Unity, nie mogą używać protokołu HTTP/2. Aby obsługiwać wszystkie aplikacje klienckie, skonfiguruj serwer, aby włączyć protokół HTTP/1.1 i HTTP/2.

Zaktualizuj protokół domyślny w pliku appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternatywnie skonfiguruj Kestrel punkty końcowe w kodzie uruchamiania.

Włączenie protokołu HTTP/1.1 i HTTP/2 na tym samym porcie wymaga protokołu TLS do negocjacji protokołu. Aby uzyskać więcej informacji, zobacz ASP.NET Core gRPC negocjacji protokołu.

Wywoływanie interfejsu gRPC-Web z przeglądarki

Aplikacje przeglądarki mogą używać biblioteki gRPC-Web do wywoływania usług gRPC. Istnieją pewne wymagania i ograniczenia dotyczące wywoływania usług gRPC z przeglądarką gRPC-Web:

  • Serwer musi zawierać konfigurację do obsługi biblioteki gRPC-Web.
  • Połączenia przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego nie są obsługiwane. Przesyłanie strumieniowe serwera jest obsługiwane.
  • Wywoływanie usług gRPC w innej domenie wymaga konfiguracji MECHANIZMU CORS na serwerze.

JavaScript gRPC-Web client

Istnieje klient gRPC-Web języka JavaScript. Aby uzyskać instrukcje dotyczące używania biblioteki gRPC-Web z języka JavaScript, zobacz pisanie kodu klienta JavaScript za pomocą biblioteki gRPC-Web.

Konfigurowanie usługi gRPC-Web przy użyciu klienta gRPC platformy .NET

Klienta gRPC platformy .NET można skonfigurować tak, aby wykonywać wywołania gRPC-Web. Jest to przydatne w przypadku Blazor WebAssembly aplikacji, które są hostowane w przeglądarce i mają te same ograniczenia HTTP kodu JavaScript. Wywoływanie interfejsu gRPC-Web z klientem platformy .NET jest takie samo jak http/2 gRPC. Jedyną modyfikacją jest sposób tworzenia kanału.

Aby użyć biblioteki gRPC-Web:

  • Dodaj odwołanie do Grpc.Net.Client.Web pakietu.
  • Upewnij się, że odwołanie do Grpc.Net.Client pakietu jest w wersji 2.29.0 lub nowszej.
  • Skonfiguruj kanał tak, aby używał polecenia GrpcWebHandler:
var channel = GrpcChannel.ForAddress("https://localhost:53305", new GrpcChannelOptions
{
    HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});

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

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

  • Konfiguruje kanał do używania biblioteki gRPC-Web.
  • Tworzy klienta i wykonuje wywołanie przy użyciu kanału.

GrpcWebHandler ma następujące opcje konfiguracji:

  • InnerHandler: Źródło HttpMessageHandler , które powoduje, że żądanie HTTP gRPC, na przykład HttpClientHandler.
  • GrpcWebMode: Typ wyliczenia określający, czy żądanie Content-Type HTTP gRPC to application/grpc-web , czy application/grpc-web-text.
    • GrpcWebMode.GrpcWeb Konfiguruje wysyłanie zawartości bez kodowania. Wartość domyślna.
    • GrpcWebMode.GrpcWebText Konfiguruje zawartość zakodowaną w formacie base64. Wymagane w przypadku wywołań przesyłania strumieniowego serwera w przeglądarkach.
  • HttpVersion: protokół Version HTTP używany do ustawiania HttpRequestMessage.Version bazowego żądania HTTP gRPC. gRPC-Web nie wymaga określonej wersji i nie zastępuje wartości domyślnej, chyba że określono.

Ważne

Wygenerowane klienci gRPC mają metody synchroniczne i asynchroniczne do wywoływania metod jednoargumentowych. Na przykład SayHello jest synchroniczna i SayHelloAsync jest asynchroniczna. Metody asynchroniczne są zawsze wymagane w programie Blazor WebAssembly. Wywołanie metody synchronicznej w Blazor WebAssembly aplikacji powoduje, że aplikacja przestaje odpowiadać.

Używanie fabryki klienta gRPC z usługą gRPC-Web

Utwórz klienta platformy .NET zgodnego z usługą gRPC-Web przy użyciu fabryki klienta gRPC:

  • Dodaj odwołania do pakietu do pliku projektu dla następujących pakietów:
  • Zarejestruj klienta gRPC za pomocą wstrzykiwania zależności (DI) przy użyciu metody rozszerzenia ogólnego AddGrpcClient . Blazor WebAssembly W aplikacji usługi są rejestrowane w usłudze DI w usłudze Program.cs.
  • Skonfiguruj GrpcWebHandler przy użyciu ConfigurePrimaryHttpMessageHandler metody rozszerzenia.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Aby uzyskać więcej informacji, zobacz integracja fabryki klienta gRPC na platformie .NET.

Dodatkowe zasoby

Dowiedz się, jak skonfigurować istniejącą usługę gRPC platformy ASP.NET Core do wywoływania z aplikacji przeglądarki przy użyciu protokołu gRPC-Web . Usługa gRPC-Web umożliwia wywoływanie usług gRPC za pomocą języka JavaScript i Blazor aplikacji przeglądarki. Nie można wywołać usługi HTTP/2 gRPC z poziomu aplikacji opartej na przeglądarce. Usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web wraz z protokołem 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.

Aby uzyskać instrukcje dotyczące tworzenia projektu gRPC, zobacz Create a .NET Core gRPC client and server in ASP.NET Core (Tworzenie klienta i serwera gRPC platformy .NET Core w programie ASP.NET Core).

ASP.NET Core gRPC-Web a Envoy

Istnieją dwie opcje dodawania biblioteki gRPC-Web do aplikacji ASP.NET Core:

  • Obsługa protokołu gRPC-Web wraz z protokołem HTTP/2 gRPC w ASP.NET Core. Ta opcja używa oprogramowania pośredniczącego dostarczonego Grpc.AspNetCore.Web przez pakiet.
  • Użyj obsługi gRPC-Web serwera proxy usługi Envoy, aby przetłumaczyć bibliotekę gRPC-Web na protokół HTTP/2 gRPC. Przetłumaczone wywołanie jest następnie przekazywane do aplikacji ASP.NET Core.

Istnieją zalety i wady dla każdego podejścia. Jeśli środowisko aplikacji używa już aplikacji Envoy jako serwera proxy, warto również użyć usługi Envoy do zapewnienia obsługi gRPC-Web. W przypadku podstawowego rozwiązania dla sieci Web gRPC,które wymaga tylko ASP.NET Core, Grpc.AspNetCore.Web jest dobrym wyborem.

Konfigurowanie usługi gRPC-Web na platformie ASP.NET Core

Usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web wraz z protokołem HTTP/2 gRPC. gRPC-Web nie wymaga żadnych zmian w usługach. Jedyną modyfikacją jest ustawienie oprogramowania middelware w programie Program.cs.

Aby włączyć usługę gRPC-Web za pomocą usługi gRPC platformy ASP.NET Core:

  • Dodaj odwołanie do Grpc.AspNetCore.Web pakietu.
  • Skonfiguruj aplikację tak, aby korzystała z biblioteki gRPC-Web, dodając UseGrpcWeb element i EnableGrpcWeb do polecenia Program.cs:
using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb();

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "This gRPC service is gRPC-Web enabled and is callable from browser apps using the gRPC-Web protocol");

app.Run();

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

  • Dodaje oprogramowanie pośredniczące gRPC-Web , UseGrpcWebpo routingu i przed punktami końcowymi.
  • Określa, że endpoints.MapGrpcService<GreeterService>() metoda obsługuje gRPC-Web z EnableGrpcWeb.

Alternatywnie można skonfigurować oprogramowanie pośredniczące gRPC-Web tak, aby wszystkie usługi domyślnie obsługiwały usługę gRPC-Web i EnableGrpcWeb nie są wymagane. Określ new GrpcWebOptions { DefaultEnabled = true } , kiedy oprogramowanie pośredniczące jest dodawane.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });

app.MapGrpcService<GreeterService>().EnableGrpcWeb();
app.MapGet("/", () => "All gRPC service are supported by default in this example, and are callable from browser apps using the gRPC-Web protocol");

app.Run();

Uwaga

Istnieje znany problem, który powoduje niepowodzenie biblioteki gRPC-Web w przypadku hostowania przez HTTP.sys na platformie .NET Core 3.x.

Obejście problemu umożliwiającego działanie biblioteki gRPC-Web na HTTP.sys jest dostępne w środowisku eksperymentalnym Grpc-web i useHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web i CORS

Zabezpieczenia przeglądarki uniemożliwiają stronie internetowej wykonywanie żądań do innej domeny niż ta, która obsłużyła stronę internetową. To ograniczenie dotyczy wykonywania wywołań gRPC-Web z aplikacjami przeglądarki. Na przykład aplikacja przeglądarki obsługiwana przez https://www.contoso.com usługę jest zablokowana do wywoływania usług gRPC-Web hostowanych w systemie https://services.contoso.com. Udostępnianie zasobów między źródłami (CORS) może służyć do złagodzenia tego ograniczenia.

Aby umożliwić aplikacji przeglądarki wykonywanie wywołań gRPC-Web między źródłami, skonfiguruj mechanizm CORS w usłudze ASP.NET Core. Użyj wbudowanej obsługi mechanizmu CORS i uwidaczniaj nagłówki specyficzne dla biblioteki gRPC za pomocą polecenia WithExposedHeaders.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

builder.Services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
    builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
}));

var app = builder.Build();

app.UseGrpcWeb();
app.UseCors();

app.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                    .RequireCors("AllowAll");

app.MapGet("/", () => "This gRPC service is gRPC-Web enabled, CORS enabled, and is callable from browser apps using the gRPC-Web protocol");

app.Run();

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

  • Wywołania AddCors umożliwiające dodanie usług CORS i skonfigurowanie zasad CORS, które uwidacznia nagłówki specyficzne dla protokołu gRPC.
  • Wywołania UseCors w celu dodania oprogramowania pośredniczącego CORS po konfiguracji routingu i przed konfiguracją punktów końcowych.
  • Określa, że endpoints.MapGrpcService<GreeterService>() metoda obsługuje mechanizm CORS z RequireCors.

gRPC-Web i przesyłanie strumieniowe

Tradycyjna funkcja gRPC za pośrednictwem protokołu HTTP/2 obsługuje przesyłanie strumieniowe klienta, serwera i dwukierunkowego przesyłania strumieniowego. GRPC-Web oferuje ograniczoną obsługę przesyłania strumieniowego:

  • Klienci przeglądarki gRPC-Web nie obsługują wywoływania metod przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego.
  • Klienci gRPC-Web platformy .NET nie obsługują wywoływania metod przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego za pośrednictwem protokołu HTTP/1.1.
  • ASP.NET Core usługi gRPC hostowane w usłudze aplikacja systemu Azure i usługach IIS nie obsługują dwukierunkowego przesyłania strumieniowego.

W przypadku korzystania z gRPC-Web zalecamy używanie tylko metod jednoargumentowych i metod przesyłania strumieniowego serwera.

Protokół HTTP

Szablon usługi gRPC platformy ASP.NET Core dołączony do zestawu SDK platformy .NET tworzy aplikację skonfigurowaną tylko dla protokołu HTTP/2. Jest to dobra wartość domyślna, gdy aplikacja obsługuje tylko tradycyjne gRPC za pośrednictwem protokołu HTTP/2. GRPC-Web działa jednak zarówno z protokołem HTTP/1.1, jak i http/2. Niektóre platformy, takie jak platforma UWP lub Unity, nie mogą używać protokołu HTTP/2. Aby obsługiwać wszystkie aplikacje klienckie, skonfiguruj serwer, aby włączyć protokół HTTP/1.1 i HTTP/2.

Zaktualizuj protokół domyślny w pliku appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternatywnie skonfiguruj Kestrel punkty końcowe w kodzie uruchamiania.

Włączenie protokołu HTTP/1.1 i HTTP/2 na tym samym porcie wymaga protokołu TLS do negocjacji protokołu. Aby uzyskać więcej informacji, zobacz ASP.NET Core gRPC negocjacji protokołu.

Wywoływanie interfejsu gRPC-Web z przeglądarki

Aplikacje przeglądarki mogą używać biblioteki gRPC-Web do wywoływania usług gRPC. Istnieją pewne wymagania i ograniczenia dotyczące wywoływania usług gRPC z przeglądarką gRPC-Web:

  • Serwer musi zawierać konfigurację do obsługi biblioteki gRPC-Web.
  • Połączenia przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego nie są obsługiwane. Przesyłanie strumieniowe serwera jest obsługiwane.
  • Wywoływanie usług gRPC w innej domenie wymaga konfiguracji MECHANIZMU CORS na serwerze.

JavaScript gRPC-Web client

Istnieje klient gRPC-Web języka JavaScript. Aby uzyskać instrukcje dotyczące używania biblioteki gRPC-Web z języka JavaScript, zobacz pisanie kodu klienta JavaScript za pomocą biblioteki gRPC-Web.

Konfigurowanie usługi gRPC-Web przy użyciu klienta gRPC platformy .NET

Klienta gRPC platformy .NET można skonfigurować tak, aby wykonywać wywołania gRPC-Web. Jest to przydatne w przypadku Blazor WebAssembly aplikacji, które są hostowane w przeglądarce i mają te same ograniczenia HTTP kodu JavaScript. Wywoływanie interfejsu gRPC-Web z klientem platformy .NET jest takie samo jak http/2 gRPC. Jedyną modyfikacją jest sposób tworzenia kanału.

Aby użyć biblioteki gRPC-Web:

  • Dodaj odwołanie do Grpc.Net.Client.Web pakietu.
  • Upewnij się, że odwołanie do Grpc.Net.Client pakietu jest w wersji 2.29.0 lub nowszej.
  • Skonfiguruj kanał tak, aby używał polecenia GrpcWebHandler:
var channel = GrpcChannel.ForAddress("https://localhost:53305", new GrpcChannelOptions
{
    HttpHandler = new GrpcWebHandler(new HttpClientHandler())
});

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

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

  • Konfiguruje kanał do używania biblioteki gRPC-Web.
  • Tworzy klienta i wykonuje wywołanie przy użyciu kanału.

GrpcWebHandler ma następujące opcje konfiguracji:

  • InnerHandler: Źródło HttpMessageHandler , które powoduje, że żądanie HTTP gRPC, na przykład HttpClientHandler.
  • GrpcWebMode: Typ wyliczenia określający, czy żądanie Content-Type HTTP gRPC to application/grpc-web , czy application/grpc-web-text.
    • GrpcWebMode.GrpcWeb Konfiguruje wysyłanie zawartości bez kodowania. Wartość domyślna.
    • GrpcWebMode.GrpcWebText Konfiguruje zawartość zakodowaną w formacie base64. Wymagane w przypadku wywołań przesyłania strumieniowego serwera w przeglądarkach.
  • HttpVersion: protokół Version HTTP używany do ustawiania HttpRequestMessage.Version bazowego żądania HTTP gRPC. gRPC-Web nie wymaga określonej wersji i nie zastępuje wartości domyślnej, chyba że określono.

Ważne

Wygenerowane klienci gRPC mają metody synchroniczne i asynchroniczne do wywoływania metod jednoargumentowych. Na przykład SayHello jest synchroniczna i SayHelloAsync jest asynchroniczna. Metody asynchroniczne są zawsze wymagane w programie Blazor WebAssembly. Wywołanie metody synchronicznej w Blazor WebAssembly aplikacji powoduje, że aplikacja przestaje odpowiadać.

Używanie fabryki klienta gRPC z usługą gRPC-Web

Utwórz klienta platformy .NET zgodnego z usługą gRPC-Web przy użyciu fabryki klienta gRPC:

  • Dodaj odwołania do pakietu do pliku projektu dla następujących pakietów:
  • Zarejestruj klienta gRPC za pomocą wstrzykiwania zależności (DI) przy użyciu metody rozszerzenia ogólnego AddGrpcClient . Blazor WebAssembly W aplikacji usługi są rejestrowane w usłudze DI w usłudze Program.cs.
  • Skonfiguruj GrpcWebHandler przy użyciu ConfigurePrimaryHttpMessageHandler metody rozszerzenia.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Aby uzyskać więcej informacji, zobacz integracja fabryki klienta gRPC na platformie .NET.

Dodatkowe zasoby

Dowiedz się, jak skonfigurować istniejącą usługę gRPC platformy ASP.NET Core do wywoływania z aplikacji przeglądarki przy użyciu protokołu gRPC-Web . Usługa gRPC-Web umożliwia wywoływanie usług gRPC za pomocą języka JavaScript i Blazor aplikacji przeglądarki. Nie można wywołać usługi HTTP/2 gRPC z poziomu aplikacji opartej na przeglądarce. Usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web wraz z protokołem 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.

Aby uzyskać instrukcje dotyczące tworzenia projektu gRPC, zobacz Create a .NET Core gRPC client and server in ASP.NET Core (Tworzenie klienta i serwera gRPC platformy .NET Core w programie ASP.NET Core).

ASP.NET Core gRPC-Web a Envoy

Istnieją dwie opcje dodawania biblioteki gRPC-Web do aplikacji ASP.NET Core:

  • Obsługa protokołu gRPC-Web wraz z protokołem HTTP/2 gRPC w ASP.NET Core. Ta opcja używa oprogramowania pośredniczącego dostarczonego Grpc.AspNetCore.Web przez pakiet.
  • Użyj obsługi gRPC-Web serwera proxy usługi Envoy, aby przetłumaczyć bibliotekę gRPC-Web na protokół HTTP/2 gRPC. Przetłumaczone wywołanie jest następnie przekazywane do aplikacji ASP.NET Core.

Istnieją zalety i wady dla każdego podejścia. Jeśli środowisko aplikacji używa już aplikacji Envoy jako serwera proxy, warto również użyć usługi Envoy do zapewnienia obsługi gRPC-Web. W przypadku podstawowego rozwiązania dla sieci Web gRPC,które wymaga tylko ASP.NET Core, Grpc.AspNetCore.Web jest dobrym wyborem.

Konfigurowanie usługi gRPC-Web na platformie ASP.NET Core

Usługi gRPC hostowane w ASP.NET Core można skonfigurować do obsługi gRPC-Web wraz z protokołem HTTP/2 gRPC. gRPC-Web nie wymaga żadnych zmian w usługach. Jedyną modyfikacją jest konfiguracja uruchamiania.

Aby włączyć usługę gRPC-Web za pomocą usługi gRPC platformy ASP.NET Core:

  • Dodaj odwołanie do Grpc.AspNetCore.Web pakietu.
  • Skonfiguruj aplikację tak, aby korzystała z biblioteki gRPC-Web, dodając UseGrpcWeb element i EnableGrpcWeb do polecenia 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:

  • Dodaje oprogramowanie pośredniczące gRPC-Web , UseGrpcWebpo routingu i przed punktami końcowymi.
  • Określa, że endpoints.MapGrpcService<GreeterService>() metoda obsługuje gRPC-Web z EnableGrpcWeb.

Alternatywnie można skonfigurować oprogramowanie pośredniczące gRPC-Web tak, aby wszystkie usługi domyślnie obsługiwały usługę gRPC-Web i EnableGrpcWeb nie są wymagane. Określ new GrpcWebOptions { DefaultEnabled = true } , kiedy oprogramowanie pośredniczące jest dodawane.

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

Istnieje znany problem, który powoduje niepowodzenie biblioteki gRPC-Web w przypadku hostowania przez HTTP.sys na platformie .NET Core 3.x.

Obejście problemu umożliwiającego działanie biblioteki gRPC-Web na HTTP.sys jest dostępne w środowisku eksperymentalnym Grpc-web i useHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web i CORS

Zabezpieczenia przeglądarki uniemożliwiają stronie internetowej wykonywanie żądań do innej domeny niż ta, która obsłużyła stronę internetową. To ograniczenie dotyczy wykonywania wywołań gRPC-Web z aplikacjami przeglądarki. Na przykład aplikacja przeglądarki obsługiwana przez https://www.contoso.com usługę jest zablokowana do wywoływania usług gRPC-Web hostowanych w systemie https://services.contoso.com. Udostępnianie zasobów między źródłami (CORS) może służyć do złagodzenia tego ograniczenia.

Aby umożliwić aplikacji przeglądarki wykonywanie wywołań gRPC-Web między źródłami, skonfiguruj mechanizm CORS w usłudze ASP.NET Core. Użyj wbudowanej obsługi mechanizmu CORS i uwidaczniaj nagłówki specyficzne dla biblioteki gRPC za pomocą polecenia 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:

  • Wywołania AddCors umożliwiające dodanie usług CORS i skonfigurowanie zasad CORS, które uwidacznia nagłówki specyficzne dla protokołu gRPC.
  • Wywołania UseCors w celu dodania oprogramowania pośredniczącego CORS po konfiguracji routingu i przed konfiguracją punktów końcowych.
  • Określa, że endpoints.MapGrpcService<GreeterService>() metoda obsługuje mechanizm CORS z RequireCors.

gRPC-Web i przesyłanie strumieniowe

Tradycyjna funkcja gRPC za pośrednictwem protokołu HTTP/2 obsługuje przesyłanie strumieniowe klienta, serwera i dwukierunkowego przesyłania strumieniowego. GRPC-Web oferuje ograniczoną obsługę przesyłania strumieniowego:

  • Klienci przeglądarki gRPC-Web nie obsługują wywoływania metod przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego.
  • Klienci gRPC-Web platformy .NET nie obsługują wywoływania metod przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego za pośrednictwem protokołu HTTP/1.1.
  • ASP.NET Core usługi gRPC hostowane w usłudze aplikacja systemu Azure i usługach IIS nie obsługują dwukierunkowego przesyłania strumieniowego.

W przypadku korzystania z gRPC-Web zalecamy używanie tylko metod jednoargumentowych i metod przesyłania strumieniowego serwera.

Protokół HTTP

Szablon usługi gRPC platformy ASP.NET Core dołączony do zestawu SDK platformy .NET tworzy aplikację skonfigurowaną tylko dla protokołu HTTP/2. Jest to dobra wartość domyślna, gdy aplikacja obsługuje tylko tradycyjne gRPC za pośrednictwem protokołu HTTP/2. GRPC-Web działa jednak zarówno z protokołem HTTP/1.1, jak i http/2. Niektóre platformy, takie jak platforma UWP lub Unity, nie mogą używać protokołu HTTP/2. Aby obsługiwać wszystkie aplikacje klienckie, skonfiguruj serwer, aby włączyć protokół HTTP/1.1 i HTTP/2.

Zaktualizuj protokół domyślny w pliku appsettings.json:

{
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http1AndHttp2"
    }
  }
}

Alternatywnie skonfiguruj Kestrel punkty końcowe w kodzie uruchamiania.

Włączenie protokołu HTTP/1.1 i HTTP/2 na tym samym porcie wymaga protokołu TLS do negocjacji protokołu. Aby uzyskać więcej informacji, zobacz ASP.NET Core gRPC negocjacji protokołu.

Wywoływanie interfejsu gRPC-Web z przeglądarki

Aplikacje przeglądarki mogą używać biblioteki gRPC-Web do wywoływania usług gRPC. Istnieją pewne wymagania i ograniczenia dotyczące wywoływania usług gRPC z przeglądarką gRPC-Web:

  • Serwer musi zawierać konfigurację do obsługi biblioteki gRPC-Web.
  • Połączenia przesyłania strumieniowego klienta i dwukierunkowego przesyłania strumieniowego nie są obsługiwane. Przesyłanie strumieniowe serwera jest obsługiwane.
  • Wywoływanie usług gRPC w innej domenie wymaga konfiguracji MECHANIZMU CORS na serwerze.

JavaScript gRPC-Web client

Istnieje klient gRPC-Web języka JavaScript. Aby uzyskać instrukcje dotyczące używania biblioteki gRPC-Web z języka JavaScript, zobacz pisanie kodu klienta JavaScript za pomocą biblioteki gRPC-Web.

Konfigurowanie usługi gRPC-Web przy użyciu klienta gRPC platformy .NET

Klienta gRPC platformy .NET można skonfigurować tak, aby wykonywać wywołania gRPC-Web. Jest to przydatne w przypadku Blazor WebAssembly aplikacji, które są hostowane w przeglądarce i mają te same ograniczenia HTTP kodu JavaScript. Wywoływanie interfejsu gRPC-Web z klientem platformy .NET jest takie samo jak http/2 gRPC. Jedyną modyfikacją jest sposób tworzenia kanału.

Aby użyć biblioteki gRPC-Web:

  • Dodaj odwołanie do Grpc.Net.Client.Web pakietu.
  • Upewnij się, że odwołanie do Grpc.Net.Client pakietu jest w wersji 2.29.0 lub nowszej.
  • Skonfiguruj kanał tak, aby używał polecenia GrpcWebHandler:
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:

  • Konfiguruje kanał do używania biblioteki gRPC-Web.
  • Tworzy klienta i wykonuje wywołanie przy użyciu kanału.

GrpcWebHandler ma następujące opcje konfiguracji:

  • InnerHandler: Źródło HttpMessageHandler , które powoduje, że żądanie HTTP gRPC, na przykład HttpClientHandler.
  • GrpcWebMode: Typ wyliczenia określający, czy żądanie Content-Type HTTP gRPC to application/grpc-web , czy application/grpc-web-text.
    • GrpcWebMode.GrpcWeb Konfiguruje wysyłanie zawartości bez kodowania. Wartość domyślna.
    • GrpcWebMode.GrpcWebText Konfiguruje zawartość zakodowaną w formacie base64. Wymagane w przypadku wywołań przesyłania strumieniowego serwera w przeglądarkach.
  • HttpVersion: protokół Version HTTP używany do ustawiania HttpRequestMessage.Version bazowego żądania HTTP gRPC. gRPC-Web nie wymaga określonej wersji i nie zastępuje wartości domyślnej, chyba że określono.

Ważne

Wygenerowane klienci gRPC mają metody synchroniczne i asynchroniczne do wywoływania metod jednoargumentowych. Na przykład SayHello jest synchroniczna i SayHelloAsync jest asynchroniczna. Metody asynchroniczne są zawsze wymagane w programie Blazor WebAssembly. Wywołanie metody synchronicznej w Blazor WebAssembly aplikacji powoduje, że aplikacja przestaje odpowiadać.

Używanie fabryki klienta gRPC z usługą gRPC-Web

Utwórz klienta platformy .NET zgodnego z usługą gRPC-Web przy użyciu fabryki klienta gRPC:

  • Dodaj odwołania do pakietu do pliku projektu dla następujących pakietów:
  • Zarejestruj klienta gRPC za pomocą wstrzykiwania zależności (DI) przy użyciu metody rozszerzenia ogólnego AddGrpcClient . Blazor WebAssembly W aplikacji usługi są rejestrowane w usłudze DI w usłudze Program.cs.
  • Skonfiguruj GrpcWebHandler przy użyciu ConfigurePrimaryHttpMessageHandler metody rozszerzenia.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Aby uzyskać więcej informacji, zobacz integracja fabryki klienta gRPC na platformie .NET.

Dodatkowe zasoby