gRPC-Web dans les applications ASP.NET Core gRPC

Par James Newton-King

Découvrez comment configurer un service ASP.NET Core gRPC existant pour qu’il puisse être appelé à partir d’applications de navigateur, à l’aide du protocole gRPC-Web. gRPC-Web permet aux applications JavaScript et Blazor du navigateur d’appeler les services gRPC. Il n’est pas possible d’appeler un service HTTP/2 gRPC à partir d’une application basée sur un navigateur. Les services gRPC hébergés dans ASP.NET Core peuvent être configurés pour prendre en charge gRPC-Web avec HTTP/2 gRPC.

Pour obtenir des instructions sur l’ajout d’un service gRPC à une application ASP.NET Core existante, consultez Ajouter des services gRPC à une application ASP.NET Core.

Pour obtenir des instructions sur la création d’un projet gRPC, consultez Créer un client et un serveur .NET Core gRPC dans ASP.NET Core.

ASP.NET Core gRPC-Web et Envoy

Il existe deux options pour ajouter gRPC-Web à une application ASP.NET Core :

  • Prendre en charge gRPC-Web avec gRPC HTTP/2 dans ASP.NET Core. Cette option utilise l’intergiciel fourni par le package Grpc.AspNetCore.Web.
  • Utilisez la prise en charge gRPC-Web du proxy Envoy pour traduire gRPC-Web en gRPC HTTP/2. L’appel traduit est ensuite transféré vers l’application ASP.NET Core.

Chaque approche présente des avantages et des inconvénients. Si l’environnement d’une application utilise déjà Envoy comme proxy, il peut être judicieux d’utiliser également Envoy pour fournir la prise en charge gRPC-Web. Pour une solution de base pour gRPC-Web qui nécessite uniquement ASP.NET Core, Grpc.AspNetCore.Web est un choix judicieux.

Configurer gRPC-Web dans ASP.NET Core

Les services gRPC hébergés dans ASP.NET Core peuvent être configurés pour prendre en charge gRPC-Web avec HTTP/2 gRPC. gRPC-Web ne nécessite aucune modification des services. La seule modification consiste à définir l’intergiciel dans Program.cs.

Pour activer gRPC-Web avec un service ASP.NET Core gRPC :

  • Ajouter une référence au package Grpc.AspNetCore.Web.
  • Configurez l’application pour utiliser gRPC-Web en ajoutant UseGrpcWeb et EnableGrpcWeb dans 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 uisng the gRPC-Web protocal");

app.Run();

Le code précédent :

  • Ajoute l’intergiciel gRPC-Web, UseGrpcWeb, après le routage et avant les points de terminaison.
  • Spécifie que la méthode endpoints.MapGrpcService<GreeterService>() prend en charge gRPC-Web avec EnableGrpcWeb.

Vous pouvez également configurer l’intergiciel gRPC-Web de sorte que tous les services prennent en charge gRPC-Web par défaut et que EnableGrpcWeb ne soit pas requis. Spécifiez new GrpcWebOptions { DefaultEnabled = true } quand l’intergiciel est ajouté.

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 uisng the gRPC-Web protocal");

app.Run();

Notes

Il existe un problème connu qui provoque l’échec de gRPC-Web quand il est hébergé par HTTP.sys dans .NET Core 3.x.

Une solution de contournement pour que gRPC-Web fonctionne sur HTTP.sys est disponible dans Grpc-web experimental and UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web et CORS

La sécurité du navigateur empêche une page Web d’envoyer des requêtes à un domaine différent de celui qui a servi la page Web. Cette restriction s’applique à la réalisation d’appels gRPC-Web avec des applications de navigateur. Par exemple, une application de navigateur fournie par https://www.contoso.com ne peut pas appeler les services gRPC-Web hébergés sur https://services.contoso.com. Le partage des ressources entre origines (CORS) peut être utilisé pour assouplir cette restriction.

Pour permettre à une application de navigateur d’effectuer des appels gRPC-Web entre origines, configurez CORS dans ASP.NET Core. Utilisez la prise en charge intégrée de CORS et exposez les en-têtes spécifiques à gRPC avec 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 uisng the gRPC-Web protocal");

app.Run();

Le code précédent :

  • Appelle AddCors pour ajouter les services CORS et configurer une stratégie CORS qui expose les en-têtes spécifiques à gRPC.
  • Appelle UseCors pour ajouter l’intergiciel CORS après la configuration du routage et avant la configuration des points de terminaison.
  • Spécifie que la méthode endpoints.MapGrpcService<GreeterService>() prend en charge CORS avec RequireCors.

gRPC-Web et diffusion en continu

gRPC sur HTTP/2 traditionnel prend en charge la diffusion en continu client, serveur et bidirectionnelle. gRPC-Web offre une prise en charge limitée de la diffusion en continu :

  • Les clients de navigateur gRPC-Web ne prennent pas en charge les méthodes d’appel par diffusion en continu client ni par diffusion en continu bidirectionnelle.
  • Les clients .NET gRPC-Web ne prennent pas en charge les méthodes d’appel par diffusion en continu client ni par diffusion en continu bidirectionnelle via HTTP/1.1.
  • Les services ASP.NET Core gRPC hébergés sur Azure App Service et IIS ne prennent pas en charge la diffusion en continu bidirectionnelle.

Quand vous utilisez gRPC-Web, nous vous recommandons d’utiliser uniquement des méthodes unaires et des méthodes de diffusion en continu serveur.

Protocole HTTP

Le modèle de services ASP.NET Core gRPC, inclus dans le kit SDK .NET, crée une application configurée uniquement pour HTTP/2. Il s’agit d’une bonne option par défaut quand une application prend en charge uniquement gRPC sur HTTP/2 traditionnel. Toutefois, gRPC-Web fonctionne à la fois avec HTTP/1.1 et HTTP/2. Certaines plateformes, comme UWP ou Unity, ne peuvent pas utiliser HTTP/2. Pour prendre en charge toutes les applications clientes, configurez le serveur pour activer HTTP/1.1 et HTTP/2.

Mettez à jour le protocole par défaut dans appsettings.json :

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

Vous pouvez également configurer des points de terminaison Kestrel dans le code de démarrage.

L’activation de HTTP/1.1 et HTTP/2 sur le même port nécessite TLS pour la négociation du protocole. Pour plus d’informations, consultez Négociation de protocole ASP.NET Core gRPC.

Appeler gRPC-Web à partir du navigateur

Les applications de navigateur peuvent utiliser gRPC-Web pour appeler les services gRPC. Il existe certaines exigences et limitations lors de l’appel de services gRPC avec gRPC-Web à partir du navigateur :

  • Le serveur doit contenir une configuration pour prendre en charge gRPC-Web.
  • Les appels de diffusion en continu client et de diffusion en continu bidirectionnelle ne sont pas pris en charge. La diffusion en continu serveur est prise en charge.
  • L’appel de services gRPC sur un autre domaine nécessite une configuration CORS sur le serveur.

Client JavaScript gRPC-Web

Un client JavaScript gRPC-Web existe. Pour obtenir des instructions sur l’utilisation de gRPC-Web à partir de JavaScript, consultez write JavaScript client code with gRPC-Web.

Configurer gRPC-Web avec le client .NET gRPC

Le client .NET gRPC peut être configuré pour effectuer des appels gRPC-Web. Cela est utile pour les applications Blazor WebAssembly, qui sont hébergées dans le navigateur et qui ont les mêmes limitations HTTP que le code JavaScript. L’appel de gRPC-Web avec un client .NET est identique à HTTP/2 gRPC. La seule modification est la façon dont le canal est créé.

Pour utiliser gRPC-Web :

  • Ajouter une référence au package Grpc.Net.Client.Web.
  • Vérifiez que la référence au package Grpc.Net.Client est la version 2.29.0 ou ultérieure.
  • Configurez le canal pour utiliser 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" });

Le code précédent :

  • Configure un canal pour utiliser gRPC-Web.
  • Crée un client et effectue un appel à l’aide du canal.

GrpcWebHandler présente les options de configuration suivantes :

  • InnerHandler : HttpMessageHandler sous-jacent qui exécute la requête HTTP de gRPC, par exemple, HttpClientHandler.
  • GrpcWebMode : type d’énumération qui spécifie si la requête HTTP de gRPC Content-Type est application/grpc-web ou application/grpc-web-text.
    • GrpcWebMode.GrpcWeb configure l’envoi de contenu sans encodage. Valeur par défaut.
    • GrpcWebMode.GrpcWebText configure le contenu encodé en base64. Requis pour les appels de diffusion en continu serveur dans les navigateurs.
  • HttpVersion : protocole HTTP Version utilisé pour définir HttpRequestMessage.Version sur la requête HTTP de gRPC sous-jacente. gRPC-Web ne nécessite pas de version spécifique et ne remplace pas la version par défaut, sauf spécification contraire.

Important

Les clients gRPC générés ont des méthodes synchrones et asynchrones pour appeler les méthodes unaires. Par exemple, SayHello est synchrone et SayHelloAsync est asynchrone. Les méthodes asynchrones sont toujours requises dans Blazor WebAssembly. L’appel d’une méthode synchrone dans une application Blazor WebAssembly fait que l’application ne répond plus.

Utiliser la fabrique de clients gRPC avec gRPC-Web

Créez un client .NET compatible avec gRPC-Web à l’aide de la fabrique de clients gRPC :

  • Ajoutez des références de package au fichier projet pour les packages suivants :
  • Inscrivez un client gRPC avec injection de dépendances à l’aide de la méthode d’extension AddGrpcClient générique. Dans une application Blazor WebAssembly, les services sont inscrits avec l’injection de dépendances dans Program.cs.
  • Configurez GrpcWebHandler à l’aide de la méthode d’extension ConfigurePrimaryHttpMessageHandler.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Pour plus d’informations, consultez Intégration de la fabrique de clients gRPC dans .NET.

Ressources supplémentaires

Découvrez comment configurer un service ASP.NET Core gRPC existant pour qu’il puisse être appelé à partir d’applications de navigateur, à l’aide du protocole gRPC-Web. gRPC-Web permet aux applications JavaScript et Blazor du navigateur d’appeler les services gRPC. Il n’est pas possible d’appeler un service HTTP/2 gRPC à partir d’une application basée sur un navigateur. Les services gRPC hébergés dans ASP.NET Core peuvent être configurés pour prendre en charge gRPC-Web avec HTTP/2 gRPC.

Pour obtenir des instructions sur l’ajout d’un service gRPC à une application ASP.NET Core existante, consultez Ajouter des services gRPC à une application ASP.NET Core.

Pour obtenir des instructions sur la création d’un projet gRPC, consultez Créer un client et un serveur .NET Core gRPC dans ASP.NET Core.

ASP.NET Core gRPC-Web et Envoy

Il existe deux options pour ajouter gRPC-Web à une application ASP.NET Core :

  • Prendre en charge gRPC-Web avec gRPC HTTP/2 dans ASP.NET Core. Cette option utilise l’intergiciel fourni par le package Grpc.AspNetCore.Web.
  • Utilisez la prise en charge gRPC-Web du proxy Envoy pour traduire gRPC-Web en gRPC HTTP/2. L’appel traduit est ensuite transféré vers l’application ASP.NET Core.

Chaque approche présente des avantages et des inconvénients. Si l’environnement d’une application utilise déjà Envoy comme proxy, il peut être judicieux d’utiliser également Envoy pour fournir la prise en charge gRPC-Web. Pour une solution de base pour gRPC-Web qui nécessite uniquement ASP.NET Core, Grpc.AspNetCore.Web est un choix judicieux.

Configurer gRPC-Web dans ASP.NET Core

Les services gRPC hébergés dans ASP.NET Core peuvent être configurés pour prendre en charge gRPC-Web avec HTTP/2 gRPC. gRPC-Web ne nécessite aucune modification des services. La seule modification consiste à définir le middelware dans Program.cs.

Pour activer gRPC-Web avec un service ASP.NET Core gRPC :

  • Ajouter une référence au package Grpc.AspNetCore.Web.
  • Configurez l’application pour utiliser gRPC-Web en ajoutant UseGrpcWeb et EnableGrpcWeb dans 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 uisng the gRPC-Web protocal");

app.Run();

Le code précédent :

  • Ajoute l’intergiciel gRPC-Web, UseGrpcWeb, après le routage et avant les points de terminaison.
  • Spécifie que la méthode endpoints.MapGrpcService<GreeterService>() prend en charge gRPC-Web avec EnableGrpcWeb.

Vous pouvez également configurer l’intergiciel gRPC-Web de sorte que tous les services prennent en charge gRPC-Web par défaut et que EnableGrpcWeb ne soit pas requis. Spécifiez new GrpcWebOptions { DefaultEnabled = true } quand l’intergiciel est ajouté.

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 uisng the gRPC-Web protocal");

app.Run();

Notes

Il existe un problème connu qui provoque l’échec de gRPC-Web quand il est hébergé par HTTP.sys dans .NET Core 3.x.

Une solution de contournement pour que gRPC-Web fonctionne sur HTTP.sys est disponible dans Grpc-web experimental and UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web et CORS

La sécurité du navigateur empêche une page Web d’envoyer des requêtes à un domaine différent de celui qui a servi la page Web. Cette restriction s’applique à la réalisation d’appels gRPC-Web avec des applications de navigateur. Par exemple, une application de navigateur fournie par https://www.contoso.com ne peut pas appeler les services gRPC-Web hébergés sur https://services.contoso.com. Le partage des ressources entre origines (CORS) peut être utilisé pour assouplir cette restriction.

Pour permettre à une application de navigateur d’effectuer des appels gRPC-Web entre origines, configurez CORS dans ASP.NET Core. Utilisez la prise en charge intégrée de CORS et exposez les en-têtes spécifiques à gRPC avec 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 uisng the gRPC-Web protocal");

app.Run();

Le code précédent :

  • Appelle AddCors pour ajouter les services CORS et configurer une stratégie CORS qui expose les en-têtes spécifiques à gRPC.
  • Appelle UseCors pour ajouter l’intergiciel CORS après la configuration du routage et avant la configuration des points de terminaison.
  • Spécifie que la méthode endpoints.MapGrpcService<GreeterService>() prend en charge CORS avec RequireCors.

gRPC-Web et diffusion en continu

gRPC sur HTTP/2 traditionnel prend en charge la diffusion en continu client, serveur et bidirectionnelle. gRPC-Web offre une prise en charge limitée de la diffusion en continu :

  • Les clients de navigateur gRPC-Web ne prennent pas en charge les méthodes d’appel par diffusion en continu client ni par diffusion en continu bidirectionnelle.
  • Les clients .NET gRPC-Web ne prennent pas en charge les méthodes d’appel par diffusion en continu client ni par diffusion en continu bidirectionnelle via HTTP/1.1.
  • Les services ASP.NET Core gRPC hébergés sur Azure App Service et IIS ne prennent pas en charge la diffusion en continu bidirectionnelle.

Quand vous utilisez gRPC-Web, nous vous recommandons d’utiliser uniquement des méthodes unaires et des méthodes de diffusion en continu serveur.

Protocole HTTP

Le modèle de services ASP.NET Core gRPC, inclus dans le kit SDK .NET, crée une application configurée uniquement pour HTTP/2. Il s’agit d’une bonne option par défaut quand une application prend en charge uniquement gRPC sur HTTP/2 traditionnel. Toutefois, gRPC-Web fonctionne à la fois avec HTTP/1.1 et HTTP/2. Certaines plateformes, comme UWP ou Unity, ne peuvent pas utiliser HTTP/2. Pour prendre en charge toutes les applications clientes, configurez le serveur pour activer HTTP/1.1 et HTTP/2.

Mettez à jour le protocole par défaut dans appsettings.json :

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

Vous pouvez également configurer des points de terminaison Kestrel dans le code de démarrage.

L’activation de HTTP/1.1 et HTTP/2 sur le même port nécessite TLS pour la négociation du protocole. Pour plus d’informations, consultez Négociation de protocole ASP.NET Core gRPC.

Appeler gRPC-Web à partir du navigateur

Les applications de navigateur peuvent utiliser gRPC-Web pour appeler les services gRPC. Il existe certaines exigences et limitations lors de l’appel de services gRPC avec gRPC-Web à partir du navigateur :

  • Le serveur doit contenir une configuration pour prendre en charge gRPC-Web.
  • Les appels de diffusion en continu client et de diffusion en continu bidirectionnelle ne sont pas pris en charge. La diffusion en continu serveur est prise en charge.
  • L’appel de services gRPC sur un autre domaine nécessite une configuration CORS sur le serveur.

Client JavaScript gRPC-Web

Un client JavaScript gRPC-Web existe. Pour obtenir des instructions sur l’utilisation de gRPC-Web à partir de JavaScript, consultez write JavaScript client code with gRPC-Web.

Configurer gRPC-Web avec le client .NET gRPC

Le client .NET gRPC peut être configuré pour effectuer des appels gRPC-Web. Cela est utile pour les applications Blazor WebAssembly, qui sont hébergées dans le navigateur et qui ont les mêmes limitations HTTP que le code JavaScript. L’appel de gRPC-Web avec un client .NET est identique à HTTP/2 gRPC. La seule modification est la façon dont le canal est créé.

Pour utiliser gRPC-Web :

  • Ajouter une référence au package Grpc.Net.Client.Web.
  • Vérifiez que la référence au package Grpc.Net.Client est la version 2.29.0 ou ultérieure.
  • Configurez le canal pour utiliser 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" });

Le code précédent :

  • Configure un canal pour utiliser gRPC-Web.
  • Crée un client et effectue un appel à l’aide du canal.

GrpcWebHandler présente les options de configuration suivantes :

  • InnerHandler : HttpMessageHandler sous-jacent qui exécute la requête HTTP de gRPC, par exemple, HttpClientHandler.
  • GrpcWebMode : type d’énumération qui spécifie si la requête HTTP de gRPC Content-Type est application/grpc-web ou application/grpc-web-text.
    • GrpcWebMode.GrpcWeb configure l’envoi de contenu sans encodage. Valeur par défaut.
    • GrpcWebMode.GrpcWebText configure le contenu encodé en base64. Requis pour les appels de diffusion en continu serveur dans les navigateurs.
  • HttpVersion : protocole HTTP Version utilisé pour définir HttpRequestMessage.Version sur la requête HTTP de gRPC sous-jacente. gRPC-Web ne nécessite pas de version spécifique et ne remplace pas la version par défaut, sauf spécification contraire.

Important

Les clients gRPC générés ont des méthodes synchrones et asynchrones pour appeler les méthodes unaires. Par exemple, SayHello est synchrone et SayHelloAsync est asynchrone. Les méthodes asynchrones sont toujours requises dans Blazor WebAssembly. L’appel d’une méthode synchrone dans une application Blazor WebAssembly fait que l’application ne répond plus.

Utiliser la fabrique de clients gRPC avec gRPC-Web

Créez un client .NET compatible avec gRPC-Web à l’aide de la fabrique de clients gRPC :

  • Ajoutez des références de package au fichier projet pour les packages suivants :
  • Inscrivez un client gRPC avec injection de dépendances à l’aide de la méthode d’extension AddGrpcClient générique. Dans une application Blazor WebAssembly, les services sont inscrits avec l’injection de dépendances dans Program.cs.
  • Configurez GrpcWebHandler à l’aide de la méthode d’extension ConfigurePrimaryHttpMessageHandler.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Pour plus d’informations, consultez Intégration de la fabrique de clients gRPC dans .NET.

Ressources supplémentaires

Découvrez comment configurer un service ASP.NET Core gRPC existant pour qu’il puisse être appelé à partir d’applications de navigateur, à l’aide du protocole gRPC-Web. gRPC-Web permet aux applications JavaScript et Blazor du navigateur d’appeler les services gRPC. Il n’est pas possible d’appeler un service HTTP/2 gRPC à partir d’une application basée sur un navigateur. Les services gRPC hébergés dans ASP.NET Core peuvent être configurés pour prendre en charge gRPC-Web avec HTTP/2 gRPC.

Pour obtenir des instructions sur l’ajout d’un service gRPC à une application ASP.NET Core existante, consultez Ajouter des services gRPC à une application ASP.NET Core.

Pour obtenir des instructions sur la création d’un projet gRPC, consultez Créer un client et un serveur .NET Core gRPC dans ASP.NET Core.

ASP.NET Core gRPC-Web et Envoy

Il existe deux options pour ajouter gRPC-Web à une application ASP.NET Core :

  • Prendre en charge gRPC-Web avec gRPC HTTP/2 dans ASP.NET Core. Cette option utilise l’intergiciel fourni par le package Grpc.AspNetCore.Web.
  • Utilisez la prise en charge gRPC-Web du proxy Envoy pour traduire gRPC-Web en gRPC HTTP/2. L’appel traduit est ensuite transféré vers l’application ASP.NET Core.

Chaque approche présente des avantages et des inconvénients. Si l’environnement d’une application utilise déjà Envoy comme proxy, il peut être judicieux d’utiliser également Envoy pour fournir la prise en charge gRPC-Web. Pour une solution de base pour gRPC-Web qui nécessite uniquement ASP.NET Core, Grpc.AspNetCore.Web est un choix judicieux.

Configurer gRPC-Web dans ASP.NET Core

Les services gRPC hébergés dans ASP.NET Core peuvent être configurés pour prendre en charge gRPC-Web avec HTTP/2 gRPC. gRPC-Web ne nécessite aucune modification des services. La seule modification est la configuration de démarrage.

Pour activer gRPC-Web avec un service ASP.NET Core gRPC :

  • Ajouter une référence au package Grpc.AspNetCore.Web.
  • Configurez l’application pour utiliser gRPC-Web en ajoutant UseGrpcWeb et EnableGrpcWeb dans 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();
    });
}

Le code précédent :

  • Ajoute l’intergiciel gRPC-Web, UseGrpcWeb, après le routage et avant les points de terminaison.
  • Spécifie que la méthode endpoints.MapGrpcService<GreeterService>() prend en charge gRPC-Web avec EnableGrpcWeb.

Vous pouvez également configurer l’intergiciel gRPC-Web de sorte que tous les services prennent en charge gRPC-Web par défaut et que EnableGrpcWeb ne soit pas requis. Spécifiez new GrpcWebOptions { DefaultEnabled = true } quand l’intergiciel est ajouté.

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

Notes

Il existe un problème connu qui provoque l’échec de gRPC-Web quand il est hébergé par HTTP.sys dans .NET Core 3.x.

Une solution de contournement pour que gRPC-Web fonctionne sur HTTP.sys est disponible dans Grpc-web experimental and UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web et CORS

La sécurité du navigateur empêche une page Web d’envoyer des requêtes à un domaine différent de celui qui a servi la page Web. Cette restriction s’applique à la réalisation d’appels gRPC-Web avec des applications de navigateur. Par exemple, une application de navigateur fournie par https://www.contoso.com ne peut pas appeler les services gRPC-Web hébergés sur https://services.contoso.com. Le partage des ressources entre origines (CORS) peut être utilisé pour assouplir cette restriction.

Pour permettre à une application de navigateur d’effectuer des appels gRPC-Web entre origines, configurez CORS dans ASP.NET Core. Utilisez la prise en charge intégrée de CORS et exposez les en-têtes spécifiques à gRPC avec 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");
    });
}

Le code précédent :

  • Appelle AddCors pour ajouter les services CORS et configurer une stratégie CORS qui expose les en-têtes spécifiques à gRPC.
  • Appelle UseCors pour ajouter l’intergiciel CORS après la configuration du routage et avant la configuration des points de terminaison.
  • Spécifie que la méthode endpoints.MapGrpcService<GreeterService>() prend en charge CORS avec RequireCors.

gRPC-Web et diffusion en continu

gRPC sur HTTP/2 traditionnel prend en charge la diffusion en continu client, serveur et bidirectionnelle. gRPC-Web offre une prise en charge limitée de la diffusion en continu :

  • Les clients de navigateur gRPC-Web ne prennent pas en charge les méthodes d’appel par diffusion en continu client ni par diffusion en continu bidirectionnelle.
  • Les clients .NET gRPC-Web ne prennent pas en charge les méthodes d’appel par diffusion en continu client ni par diffusion en continu bidirectionnelle via HTTP/1.1.
  • Les services ASP.NET Core gRPC hébergés sur Azure App Service et IIS ne prennent pas en charge la diffusion en continu bidirectionnelle.

Quand vous utilisez gRPC-Web, nous vous recommandons d’utiliser uniquement des méthodes unaires et des méthodes de diffusion en continu serveur.

Protocole HTTP

Le modèle de services ASP.NET Core gRPC, inclus dans le kit SDK .NET, crée une application configurée uniquement pour HTTP/2. Il s’agit d’une bonne option par défaut quand une application prend en charge uniquement gRPC sur HTTP/2 traditionnel. Toutefois, gRPC-Web fonctionne à la fois avec HTTP/1.1 et HTTP/2. Certaines plateformes, comme UWP ou Unity, ne peuvent pas utiliser HTTP/2. Pour prendre en charge toutes les applications clientes, configurez le serveur pour activer HTTP/1.1 et HTTP/2.

Mettez à jour le protocole par défaut dans appsettings.json :

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

Vous pouvez également configurer des points de terminaison Kestrel dans le code de démarrage.

L’activation de HTTP/1.1 et HTTP/2 sur le même port nécessite TLS pour la négociation du protocole. Pour plus d’informations, consultez Négociation de protocole ASP.NET Core gRPC.

Appeler gRPC-Web à partir du navigateur

Les applications de navigateur peuvent utiliser gRPC-Web pour appeler les services gRPC. Il existe certaines exigences et limitations lors de l’appel de services gRPC avec gRPC-Web à partir du navigateur :

  • Le serveur doit contenir une configuration pour prendre en charge gRPC-Web.
  • Les appels de diffusion en continu client et de diffusion en continu bidirectionnelle ne sont pas pris en charge. La diffusion en continu serveur est prise en charge.
  • L’appel de services gRPC sur un autre domaine nécessite une configuration CORS sur le serveur.

Client JavaScript gRPC-Web

Un client JavaScript gRPC-Web existe. Pour obtenir des instructions sur l’utilisation de gRPC-Web à partir de JavaScript, consultez write JavaScript client code with gRPC-Web.

Configurer gRPC-Web avec le client .NET gRPC

Le client .NET gRPC peut être configuré pour effectuer des appels gRPC-Web. Cela est utile pour les applications Blazor WebAssembly, qui sont hébergées dans le navigateur et qui ont les mêmes limitations HTTP que le code JavaScript. L’appel de gRPC-Web avec un client .NET est identique à HTTP/2 gRPC. La seule modification est la façon dont le canal est créé.

Pour utiliser gRPC-Web :

  • Ajouter une référence au package Grpc.Net.Client.Web.
  • Vérifiez que la référence au package Grpc.Net.Client est la version 2.29.0 ou ultérieure.
  • Configurez le canal pour utiliser 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" });

Le code précédent :

  • Configure un canal pour utiliser gRPC-Web.
  • Crée un client et effectue un appel à l’aide du canal.

GrpcWebHandler présente les options de configuration suivantes :

  • InnerHandler : HttpMessageHandler sous-jacent qui exécute la requête HTTP de gRPC, par exemple, HttpClientHandler.
  • GrpcWebMode : type d’énumération qui spécifie si la requête HTTP de gRPC Content-Type est application/grpc-web ou application/grpc-web-text.
    • GrpcWebMode.GrpcWeb configure l’envoi de contenu sans encodage. Valeur par défaut.
    • GrpcWebMode.GrpcWebText configure le contenu encodé en base64. Requis pour les appels de diffusion en continu serveur dans les navigateurs.
  • HttpVersion : protocole HTTP Version utilisé pour définir HttpRequestMessage.Version sur la requête HTTP de gRPC sous-jacente. gRPC-Web ne nécessite pas de version spécifique et ne remplace pas la version par défaut, sauf spécification contraire.

Important

Les clients gRPC générés ont des méthodes synchrones et asynchrones pour appeler les méthodes unaires. Par exemple, SayHello est synchrone et SayHelloAsync est asynchrone. Les méthodes asynchrones sont toujours requises dans Blazor WebAssembly. L’appel d’une méthode synchrone dans une application Blazor WebAssembly fait que l’application ne répond plus.

Utiliser la fabrique de clients gRPC avec gRPC-Web

Créez un client .NET compatible avec gRPC-Web à l’aide de la fabrique de clients gRPC :

  • Ajoutez des références de package au fichier projet pour les packages suivants :
  • Inscrivez un client gRPC avec injection de dépendances à l’aide de la méthode d’extension AddGrpcClient générique. Dans une application Blazor WebAssembly, les services sont inscrits avec l’injection de dépendances dans Program.cs.
  • Configurez GrpcWebHandler à l’aide de la méthode d’extension ConfigurePrimaryHttpMessageHandler.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Pour plus d’informations, consultez Intégration de la fabrique de clients gRPC dans .NET.

Ressources supplémentaires