Verwenden von gRPC in Browser-AppsUse gRPC in browser apps
Von James Newton-KingBy James Newton-King
Erfahren Sie, wie Sie einen vorhandenen gRPC-Dienst für ASP.NET Core so konfigurieren, dass er mit dem gRPC-Web-Protokoll von Browser-Apps aus aufgerufen werden können.Learn how to configure an existing ASP.NET Core gRPC service to be callable from browser apps, using the gRPC-Web protocol. gRPC-Web erlaubt JavaScript- und Blazor-Apps im Browser, gRPC-Dienste aufzurufen.gRPC-Web allows browser JavaScript and Blazor apps to call gRPC services. Es ist nicht möglich, einen HTTP/2-gRPC-Dienst von einer browserbasierten App aus aufzurufen.It's not possible to call an HTTP/2 gRPC service from a browser-based app. gRPC-Dienste, die in ASP.NET Core gehostet werden, können so konfiguriert werden, dass sie neben HTTP/2 gRPC auch gRPC-Web unterstützen.gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC.
Anweisungen zum Hinzufügen eines gRPC-Diensts zu einer vorhandenen ASP.NET Core-App finden Sie unter Hinzufügen von gRPC-Diensten zu einer ASP.NET Core-App.For instructions on adding a gRPC service to an existing ASP.NET Core app, see Add gRPC services to an ASP.NET Core app.
Anweisungen zum Erstellen eines gRPC-Projekts finden Sie unter Erstellen eines .NET Core-gRPC-Clients und -Servers in ASP.NET Core.For instructions on creating a gRPC project, see Erstellen eines .NET Core-gRPC-Clients und -Servers in ASP.NET Core.
gRPC-Web in ASP.NET Core im Vergleich zu EnvoygRPC-Web in ASP.NET Core vs. Envoy
Es gibt zwei Möglichkeiten zum Hinzufügen von gRPC-Web zu einer ASP.NET Core-App:There are two choices for how to add gRPC-Web to an ASP.NET Core app:
- Unterstützung von gRPC-Web parallel zu gRPC HTTP/2 in ASP.NET Core.Support gRPC-Web alongside gRPC HTTP/2 in ASP.NET Core. Diese Option verwendet die mit dem
Grpc.AspNetCore.Web
-Paket bereitgestellte Middleware.This option uses middleware provided by theGrpc.AspNetCore.Web
package. - Verwenden Sie die gRPC-Webunterstützung des Envoy Proxys, um gRPC-Web in gRPC HTTP/2 zu übersetzen.Use the Envoy proxy's gRPC-Web support to translate gRPC-Web to gRPC HTTP/2. Der übersetzte Aufruf wird dann an die ASP.NET Core-App weitergeleitet.The translated call is then forwarded onto the ASP.NET Core app.
Beide Ansätze haben Vor- und Nachteile.There are pros and cons to each approach. Wenn die Umgebung einer App bereits Envoy als Proxy verwendet, kann es sinnvoll sein, Envoy auch zur Bereitstellung von gRPC-Webunterstützung zu verwenden.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. Als einfache Lösung für gRPC-Web, die nur ASP.NET Core erfordert, ist Grpc.AspNetCore.Web
eine gute Wahl.For a basic solution for gRPC-Web that only requires ASP.NET Core, Grpc.AspNetCore.Web
is a good choice.
Konfigurieren von gRPC-Web in ASP.NET CoreConfigure gRPC-Web in ASP.NET Core
gRPC-Dienste, die in ASP.NET Core gehostet werden, können so konfiguriert werden, dass sie neben HTTP/2 gRPC auch gRPC-Web unterstützen.gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC. Für gRPC-Web sind keine Änderungen der Dienste erforderlich.gRPC-Web does not require any changes to services. Die einzige Änderung ist die Startkonfiguration.The only modification is startup configuration.
So aktivieren Sie gRPC-Web mit einem ASP.NET Core gRPC-DienstTo enable gRPC-Web with an ASP.NET Core gRPC service:
- Fügen Sie einen Verweis auf das Paket Grpc.AspNetCore.Web hinzu.Add a reference to the Grpc.AspNetCore.Web package.
- Konfigurieren Sie die App zur Verwendung von gRPC-Web, indem Sie
UseGrpcWeb
undEnableGrpcWeb
zu Startup.cs hinzufügen:Configure the app to use gRPC-Web by addingUseGrpcWeb
andEnableGrpcWeb
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();
});
}
Der vorangehende Code:The preceding code:
- Fügt die gRPC-Web-Middleware,
UseGrpcWeb
, nach dem Routing und vor den Endpunkten hinzu.Adds the gRPC-Web middleware,UseGrpcWeb
, after routing and before endpoints. - Gibt die Methode
endpoints.MapGrpcService<GreeterService>()
an, die gRPC-Web mitEnableGrpcWeb
unterstützt.Specifies theendpoints.MapGrpcService<GreeterService>()
method supports gRPC-Web withEnableGrpcWeb
.
Alternativ kann die gRPC-Web-Middleware so konfiguriert werden, dass alle Dienste standardmäßig gRPC-Web unterstützen und EnableGrpcWeb
nicht erforderlich ist.Alternatively, the gRPC-Web middleware can be configured so all services support gRPC-Web by default and EnableGrpcWeb
isn't required. Geben Sie new GrpcWebOptions { DefaultEnabled = true }
an, wenn die Middleware hinzugefügt wird.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>();
});
}
}
Hinweis
Es gibt ein bekanntes Problem, das dazu führen kann, dass gRPC-Web fehlschlägt, wenn es von Htpp.sys in .NET Core 3.x gehostet wird.There is a known issue that causes gRPC-Web to fail when hosted by Http.sys in .NET Core 3.x.
Eine Problemumgehung, um gRPC-Web auf Http.sys betreiben zu können, finden Sie hier.A workaround to get gRPC-Web working on Http.sys is available here.
gRPC-Web und CORSgRPC-Web and CORS
Die Browsersicherheit verhindert, dass eine Webseite Anforderungen an eine andere Domäne als diejenige stellt, die die Webseite versorgt hat.Browser security prevents a web page from making requests to a different domain than the one that served the web page. Diese Einschränkung gilt für das Durchführen von gRPC-Webaufrufen mit Browser-Apps.This restriction applies to making gRPC-Web calls with browser apps. So wird z. B. eine Browser-App, die von https://www.contoso.com
versorgt wird, daran gehindert, gRPC-Web-Dienste aufzurufen, die auf https://services.contoso.com
gehostet werden.For example, a browser app served by https://www.contoso.com
is blocked from calling gRPC-Web services hosted on https://services.contoso.com
. Die Ressourcenfreigabe zwischen verschiedenen Ursprüngen (Cross Origin Resource Sharing, CORS) kann verwendet werden, um diese Einschränkung zu lockern.Cross Origin Resource Sharing (CORS) can be used to relax this restriction.
Damit eine Browser-App die Möglichkeit hat, gRPC-Web-Aufrufe ursprungsübergreifend zu tätigen, richten Sie CORS in ASP.NET Core ein.To allow a browser app to make cross-origin gRPC-Web calls, set up CORS in ASP.NET Core. Verwenden Sie die integrierte CORS-Unterstützung, und machen Sie gRPC-spezifische Header mit WithExposedHeaders verfügbar.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");
});
}
Der vorangehende Code:The preceding code:
- Ruft
AddCors
zum Hinzufügen von CORS-Diensten auf und konfiguriert eine CORS-Richtlinie, die gRPC-spezifische Header verfügbar macht.CallsAddCors
to add CORS services and configures a CORS policy that exposes gRPC-specific headers. - Ruft
UseCors
zum Hinzufügen der CORS-Middleware nach dem Routing und vor den Endpunkten auf.CallsUseCors
to add the CORS middleware after routing and before endpoints. - Gibt die Methode
endpoints.MapGrpcService<GreeterService>()
an, die CORS mitRequiresCors
unterstützt.Specifies theendpoints.MapGrpcService<GreeterService>()
method supports CORS withRequiresCors
.
gRPC-Web und StreaminggRPC-Web and streaming
Herkömmliches gRPC über HTTP/2 unterstützt das Streamen in alle Richtungen.Traditional gRPC over HTTP/2 supports streaming in all directions. gRPC-Web bietet eingeschränkte Unterstützung für Streaming:gRPC-Web offers limited support for streaming:
- gRPC-Web-Browserclients unterstützen das Aufrufen von Clientstreaming- und bidirektionalen Streamingmethoden nicht.gRPC-Web browser clients don't support calling client streaming and bidirectional streaming methods.
- ASP.NET Core-gRPC-Dienste, die in Azure App Service und IIS gehostet werden, unterstützen das bidirektionale Streaming nicht.ASP.NET Core gRPC services hosted on Azure App Service and IIS don't support bidirectional streaming.
Bei der Verwendung von gRPC-Web wird nur der Einsatz von unären Methoden und Serverstreamingmethoden empfohlen.When using gRPC-Web, we only recommend the use of unary methods and server streaming methods.
Aufrufen von gRPC-Web über den BrowserCall gRPC-Web from the browser
Browser-Apps können gRPC-Web verwenden, um gRPC-Dienste aufzurufen.Browser apps can use gRPC-Web to call gRPC services. Es gibt einige Anforderungen und Einschränkungen beim Aufrufen von gRPC-Diensten mit gRPC-Web aus dem Browser heraus:There are some requirements and limitations when calling gRPC services with gRPC-Web from the browser:
- Der Server muss für die Unterstützung von gRPC-Web konfiguriert worden sein.The server must have been configured to support gRPC-Web.
- Clientstreaming und bidirektionale Streamingaufrufe werden nicht unterstützt.Client streaming and bidirectional streaming calls aren't supported. Das Serverstreaming wird unterstützt.Server streaming is supported.
- Das Aufrufen von gRPC-Diensten in einer anderen Domäne erfordert die Konfiguration von CORS auf dem Server.Calling gRPC services on a different domain requires CORS to be configured on the server.
JavaScript gRPC-Web-ClientJavaScript gRPC-Web client
Es gibt einen JavaScript gRPC-Web-Client.There is a JavaScript gRPC-Web client. Anweisungen zur Verwendung von gRPC-Web aus JavaScript heraus finden Sie unter Schreiben von JavaScript-Clientcode mit gRPC-Web.For instructions on how to use gRPC-Web from JavaScript, see write JavaScript client code with gRPC-Web.
Konfigurieren von gRPC-Web mit dem .NET gRPC-ClientConfigure gRPC-Web with the .NET gRPC client
Der .NET gRPC-Client kann für gRPC-Web-Aufrufe konfiguriert werden.The .NET gRPC client can be configured to make gRPC-Web calls. Dies ist nützlich für Blazor WebAssembly-Apps, die im Browser gehostet werden und dieselben HTTP-Einschränkungen des JavaScript-Codes aufweisen.This is useful for Blazor WebAssembly apps, which are hosted in the browser and have the same HTTP limitations of JavaScript code. Das Aufrufen von gRPC-Web mit einem .NET-Client ist dasselbe wie das Aufrufen von HTTP/2 gRPC.Calling gRPC-Web with a .NET client is the same as HTTP/2 gRPC. Die einzige Änderung besteht darin, wie der Kanal erstellt wird.The only modification is how the channel is created.
So verwenden Sie gRPC-WebTo use gRPC-Web:
- Fügen Sie einen Verweis auf das Paket Grpc.Net.Client.Web hinzu.Add a reference to the Grpc.Net.Client.Web package.
- Stellen Sie sicher, dass der Verweis auf das Paket Grpc.Net.Client 2.29.0 oder höher ist.Ensure the reference to Grpc.Net.Client package is 2.29.0 or greater.
- Konfigurieren Sie den Kanal für die Verwendung von
GrpcWebHandler
:Configure the channel to use theGrpcWebHandler
:
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" });
Der vorangehende Code:The preceding code:
- Konfiguriert einen Kanal zur Verwendung von gRPC-Web.Configures a channel to use gRPC-Web.
- Erstellt einen Client und tätigt einen Aufruf über den Kanal.Creates a client and makes a call using the channel.
GrpcWebHandler
hat die folgenden Konfigurationsoptionen:GrpcWebHandler
has the following configuration options:
- InnerHandler: Der zugrundeliegende HttpMessageHandler, der die gRPC HTTP-Anforderung stellt, z. B.
HttpClientHandler
.InnerHandler: The underlying HttpMessageHandler that makes the gRPC HTTP request, for example,HttpClientHandler
. - GrpcWebMode: Ein Enumerationstyp, der angibt, ob die gRPC-HTTP-Anforderung
Content-Type
application/grpc-web
oderapplication/grpc-web-text
ist.GrpcWebMode: An enumeration type that specifies whether the gRPC HTTP requestContent-Type
isapplication/grpc-web
orapplication/grpc-web-text
.GrpcWebMode.GrpcWeb
konfiguriert Inhalte, die ohne Codierung gesendet werden.GrpcWebMode.GrpcWeb
configures content to be sent without encoding. Standardwert.Default value.GrpcWebMode.GrpcWebText
konfiguriert den Inhalt so, dass er Base64-codiert ist.GrpcWebMode.GrpcWebText
configures content to be base64 encoded. Erforderlich für Serverstreamingaufrufe in Browsern.Required for server streaming calls in browsers.
- HttpVersion: Die
Version
des HTTP-Protokolls, die verwendet wird, um HttpRequestMessage.Version für die zugrunde liegende gRPC-HTTP-Anforderung festzulegen.HttpVersion: HTTP protocolVersion
used to set HttpRequestMessage.Version on the underlying gRPC HTTP request. gRPC-Web erfordert keine bestimmte Version und setzt die Standardeinstellung nicht außer Kraft, sofern nicht anders angegeben.gRPC-Web doesn't require a specific version and doesn't override the default unless specified.
Wichtig
Generierte gRPC-Clients verfügen über synchrone und asynchrone Methoden für den Aufruf unärer Methoden.Generated gRPC clients have sync and async methods for calling unary methods. Beispiel: SayHello
ist synchron und SayHelloAsync
ist asynchron.For example, SayHello
is sync and SayHelloAsync
is async. Der Aufruf einer synchronen Methode in einer Blazor WebAssembly-App führt dazu, dass die App nicht mehr reagiert.Calling a sync method in a Blazor WebAssembly app will cause the app to become unresponsive. Asynchrone Methoden müssen in Blazor WebAssembly immer verwendet werden.Async methods must always be used in Blazor WebAssembly.
Verwenden der gRPC-Clientfactory mit gRPC-WebUse gRPC client factory with gRPC-Web
Ein mit gRPC-Web kompatibler .NET-Client kann mithilfe der gRPC-Integration mit HttpClientFactory erstellt werden.A gRPC-Web compatible .NET client can be created using gRPC's integration with HttpClientFactory.
So verwenden Sie gRPC-Web mit der Clientfactory:To use gRPC-Web with client factory:
- Fügen Sie der Projektdatei Paketverweise für folgende Pakete hinzu:Add package references to the project file for the following packages:
- Registrieren Sie einen gRPC-Client mit Dependency Injection (DI), indem Sie die generische Erweiterungsmethode
AddGrpcClient
verwenden.Register a gRPC client with dependency injection (DI) using the genericAddGrpcClient
extension method. In einer Blazor WebAssembly-App werden Dienste mit DI inProgram.cs
registriert.In a Blazor WebAssembly app, services are registered with DI inProgram.cs
. - Konfigurieren Sie
GrpcWebHandler
mithilfe der Erweiterungsmethode ConfigurePrimaryHttpMessageHandler.ConfigureGrpcWebHandler
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()));
Weitere Informationen finden Sie unter gRPC-Integration von Clientfactory in .NET Core.For more information, see gRPC-Integration von Clientfactory in .NET Core.