Partilhar via


gRPC-Web em aplicativos gRPC ASP.NET Core

Note

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Warning

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.

Por James Newton-King

Saiba como configurar um serviço gRPC ASP.NET Core existente para ser chamável a partir de aplicativos do navegador, usando o protocolo gRPC-Web . O gRPC-Web permite que o JavaScript do navegador e Blazor os aplicativos chamem os serviços gRPC. Não é possível chamar um serviço gRPC HTTP/2 a partir de um aplicativo baseado em navegador. Os serviços gRPC hospedados no ASP.NET Core podem ser configurados para suportar gRPC-Web juntamente com HTTP/2 gRPC.

Para obter instruções sobre como adicionar um serviço gRPC a um aplicativo ASP.NET Core existente, consulte Adicionar serviços gRPC a um aplicativo ASP.NET Core.

Para obter instruções sobre como criar um projeto gRPC, consulte Criar um cliente e servidor gRPC .NET no ASP.NET Core.

ASP.NET Core gRPC-Web contra Envoy

Há duas opções de como adicionar gRPC-Web a um aplicativo ASP.NET Core:

  • Suporte gRPC-Web juntamente com gRPC HTTP/2 no ASP.NET Core. Esta opção usa middleware fornecido pelo Grpc.AspNetCore.Web pacote.
  • Utilize o suporte gRPC-Web do proxy Envoy para traduzir gRPC-Web para gRPC HTTP/2. A chamada traduzida é então encaminhada para o aplicativo ASP.NET Core.

Há prós e contras em cada abordagem. Se o ambiente de um aplicativo já estiver usando o Envoy como proxy, talvez faça sentido usar também o Envoy para fornecer suporte gRPC-Web. Para uma solução básica para gRPC-Web que requer apenas ASP.NET Core, Grpc.AspNetCore.Web é uma boa escolha.

Configurar o gRPC-Web no ASP.NET Core

Os serviços gRPC hospedados no ASP.NET Core podem ser configurados para suportar gRPC-Web juntamente com HTTP/2 gRPC. O gRPC-Web não requer alterações nos serviços. A única modificação está na configuração do middleware em Program.cs.

Para habilitar o gRPC-Web com um serviço gRPC ASP.NET Core:

  • Adicione uma referência ao Grpc.AspNetCore.Web pacote.
  • Configure o aplicativo para usar gRPC-Web adicionando UseGrpcWeb e EnableGrpcWeb para 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();

O código anterior:

  • Adiciona o middleware gRPC-Web, UseGrpcWeb, depois do roteamento e antes dos pontos de extremidade.
  • Especifica que o endpoints.MapGrpcService<GreeterService>() método suporta gRPC-Web com EnableGrpcWeb.

Como alternativa, o middleware gRPC-Web pode ser configurado para que todos os serviços suportem gRPC-Web por padrão e EnableGrpcWeb não seja necessário. Especifique new GrpcWebOptions { DefaultEnabled = true } quando o middleware é adicionado.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

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

app.MapGrpcService<GreeterService>();
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();

Note

Há um problema conhecido que faz com que o gRPC-Web falhe quando hospedado por HTTP.sys no .NET Core 3.x.

Uma solução alternativa para fazer com que o gRPC-Web funcione em HTTP.sys está disponível em Grpc-web experimental e UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web e CORS

A segurança do navegador impede que uma página da Web faça solicitações para um domínio diferente daquele que serviu a página da Web. Essa restrição se aplica a fazer chamadas gRPC-Web com aplicativos do navegador. Por exemplo, um aplicativo de navegador servido por https://www.contoso.com é impedido de chamar serviços gRPC-Web hospedados no https://services.contoso.com. O compartilhamento de recursos entre origens (CORS) pode ser usado para relaxar essa restrição.

Para permitir que um aplicativo de navegador faça chamadas gRPC-Web de origem cruzada, configure o CORS no ASP.NET Core. Utilize o suporte CORS interno e exponha cabeçalhos específicos do gRPC com 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", 
                "Grpc-Status-Details-Bin");
}));

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

O código anterior:

  • Chama AddCors para adicionar serviços de CORS e configurar uma política de CORS que exponha cabeçalhos específicos do gRPC.
  • Chama UseCors para adicionar o middleware CORS após a configuração de roteamento e antes da definição de pontos finais.
  • Especifica que o endpoints.MapGrpcService<GreeterService>() método suporta CORS com RequireCors.

gRPC-Web e streaming

O gRPC tradicional sobre HTTP/2 suporta cliente, servidor e streaming bidirecional. gRPC-Web oferece suporte limitado para streaming:

  • Os clientes de navegador do gRPC-Web não suportam chamadas de métodos de streaming do cliente e de streaming bidirecional.
  • Os clientes gRPC-Web .NET não suportam a utilização de métodos de client streaming e de transmissão bidirecional através de HTTP/1.1.
  • ASP.NET Os principais serviços gRPC hospedados no Serviço de Aplicativo do Azure e no IIS não oferecem suporte a streaming bidirecional.

Ao usar gRPC-Web, recomendamos apenas o uso de métodos unários e métodos de streaming de servidor.

Protocolo HTTP

O modelo de serviço gRPC ASP.NET Core, incluído no SDK do .NET, cria um aplicativo configurado apenas para HTTP/2. Este é um bom padrão quando um aplicativo suporta apenas gRPC tradicional sobre HTTP/2. gRPC-Web, no entanto, funciona com HTTP/1.1 e HTTP/2. Algumas plataformas, como UWP ou Unity, não podem usar HTTP/2. Para suportar todos os aplicativos cliente, configure o servidor para habilitar HTTP/1.1 e HTTP/2.

Atualize o protocolo padrão em appsettings.json:

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

Como alternativa, configure Kestrel endpoints no código de arranque.

Habilitar HTTP/1.1 e HTTP/2 na mesma porta requer TLS para negociação de protocolo. Para obter mais informações, consulte negociação do protocolo gRPC do ASP.NET Core.

Chame gRPC-Web a partir do navegador

As aplicações de navegador podem usar gRPC-Web para chamar serviços gRPC. Existem alguns requisitos e limitações ao chamar serviços gRPC com gRPC-Web a partir do navegador:

  • O servidor deve conter configuração para suportar gRPC-Web.
  • Streaming de cliente e chamadas de streaming bidirecionais não são suportados. O streaming do servidor é suportado.
  • Chamar serviços gRPC em um domínio diferente requer configuração CORS no servidor.

Cliente JavaScript gRPC-Web

Existe um cliente JavaScript gRPC-Web. Para obter instruções sobre como usar gRPC-Web a partir de JavaScript, consulte escrever código de cliente JavaScript com gRPC-Web.

Configurar gRPC-Web com o cliente gRPC .NET

O cliente gRPC .NET pode ser configurado para fazer chamadas gRPC-Web. Isso é útil para Blazor WebAssembly aplicativos, que são hospedados no navegador e têm as mesmas limitações HTTP do código JavaScript. Chamar gRPC-Web com um cliente .NET é o mesmo que HTTP/2 gRPC. A única modificação é como o canal é criado.

Para usar o gRPC-Web:

  • Adicione uma referência ao Grpc.Net.Client.Web pacote.
  • Verifique se a referência ao pacote é a Grpc.Net.Client versão 2.29.0 ou posterior.
  • Configure o canal para utilizar o 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" });

O código anterior:

  • Configura um canal para usar gRPC-Web.
  • Cria um cliente e faz uma chamada usando o canal.

GrpcWebHandler tem as seguintes opções de configuração:

  • InnerHandler: O componente básico HttpMessageHandler que realiza a solicitação HTTP do gRPC, por exemplo, HttpClientHandler.
  • GrpcWebMode: Um tipo de enumeração que especifica se a solicitação Content-Type HTTP gRPC é application/grpc-web ou application/grpc-web-text.
    • GrpcWebMode.GrpcWeb Configura o envio de conteúdo sem codificação. Valor padrão.
    • GrpcWebMode.GrpcWebText Configura o conteúdo codificado em Base64. Necessário para chamadas de streaming de servidor em navegadores.

GrpcChannelOptions.HttpVersion e GrpcChannelOptions.HttpVersionPolicy pode ser usado para configurar a versão do protocolo HTTP.

Important

Os clientes gRPC gerados têm métodos síncronos e assíncronos para chamar métodos unários. Por exemplo, SayHello é síncrono e SayHelloAsync assíncrono. Métodos assíncronos são sempre necessários no Blazor WebAssembly. Chamar um método síncrono em um Blazor WebAssembly aplicativo faz com que o aplicativo pare de responder.

Utilize a fábrica de clientes gRPC com gRPC-Web

Crie um cliente .NET compatível com gRPC-Web usando a fábrica do cliente gRPC:

  • Adicione referências de pacote ao arquivo de projeto para os seguintes pacotes:
  • Registre um cliente gRPC com injeção de dependência (DI) usando o método de extensão genérico AddGrpcClient . Em um Blazor WebAssembly aplicativo, os serviços são registrados com DI em Program.cs.
  • Configure GrpcWebHandler usando o método de extensão ConfigurePrimaryHttpMessageHandler.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Para obter mais informações, consulte integração de fábrica do cliente gRPC no .NET.

Recursos adicionais

Saiba como configurar um serviço gRPC ASP.NET Core existente para ser chamável a partir de aplicativos do navegador, usando o protocolo gRPC-Web . O gRPC-Web permite que o JavaScript do navegador e Blazor os aplicativos chamem os serviços gRPC. Não é possível chamar um serviço gRPC HTTP/2 a partir de um aplicativo baseado em navegador. Os serviços gRPC hospedados no ASP.NET Core podem ser configurados para suportar gRPC-Web juntamente com HTTP/2 gRPC.

Para obter instruções sobre como adicionar um serviço gRPC a um aplicativo ASP.NET Core existente, consulte Adicionar serviços gRPC a um aplicativo ASP.NET Core.

Para obter instruções sobre como criar um projeto gRPC, consulte Criar um cliente e servidor gRPC .NET no ASP.NET Core.

ASP.NET Core gRPC-Web versus Envoy

Há duas opções de como adicionar gRPC-Web a um aplicativo ASP.NET Core:

  • Suporte gRPC-Web juntamente com gRPC HTTP/2 no ASP.NET Core. Esta opção usa middleware fornecido pelo Grpc.AspNetCore.Web pacote.
  • Utilize o suporte gRPC-Web do proxy Envoy para traduzir gRPC-Web para gRPC HTTP/2. A chamada traduzida é então encaminhada para o aplicativo ASP.NET Core.

Há prós e contras em cada abordagem. Se o ambiente de um aplicativo já estiver usando o Envoy como proxy, talvez faça sentido usar também o Envoy para fornecer suporte gRPC-Web. Para uma solução básica para gRPC-Web que requer apenas ASP.NET Core, Grpc.AspNetCore.Web é uma boa escolha.

Configurar o gRPC-Web no ASP.NET Core

Os serviços gRPC hospedados no ASP.NET Core podem ser configurados para suportar gRPC-Web juntamente com HTTP/2 gRPC. O gRPC-Web não requer alterações nos serviços. A única modificação está na configuração do middelware em Program.cs.

Para habilitar o gRPC-Web com um serviço gRPC ASP.NET Core:

  • Adicione uma referência ao Grpc.AspNetCore.Web pacote.
  • Configure o aplicativo para usar gRPC-Web adicionando UseGrpcWeb e EnableGrpcWeb para 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();

O código anterior:

  • Adiciona o middleware gRPC-Web, UseGrpcWeb, depois do roteamento e antes dos pontos de extremidade.
  • Especifica que o endpoints.MapGrpcService<GreeterService>() método suporta gRPC-Web com EnableGrpcWeb.

Como alternativa, o middleware gRPC-Web pode ser configurado para que todos os serviços suportem gRPC-Web por padrão e EnableGrpcWeb não seja necessário. Especifique new GrpcWebOptions { DefaultEnabled = true } quando o middleware é adicionado.

using GrpcGreeter.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddGrpc();

var app = builder.Build();

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

app.MapGrpcService<GreeterService>();
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();

Note

Há um problema conhecido que faz com que o gRPC-Web falhe quando hospedado por HTTP.sys no .NET Core 3.x.

Uma solução alternativa para fazer com que o gRPC-Web funcione em HTTP.sys está disponível em Grpc-web experimental e UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web e CORS

A segurança do navegador impede que uma página da Web faça solicitações para um domínio diferente daquele que serviu a página da Web. Essa restrição se aplica a fazer chamadas gRPC-Web com aplicativos do navegador. Por exemplo, um aplicativo de navegador servido por https://www.contoso.com é impedido de chamar serviços gRPC-Web hospedados no https://services.contoso.com. O compartilhamento de recursos entre origens (CORS) pode ser usado para relaxar essa restrição.

Para permitir que um aplicativo de navegador faça chamadas gRPC-Web de origem cruzada, configure o CORS no ASP.NET Core. Utilize o suporte CORS interno e exponha cabeçalhos específicos do gRPC com 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", 
                "Grpc-Status-Details-Bin");
}));

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

O código anterior:

  • Chama AddCors para adicionar serviços de CORS e configurar uma política de CORS que exponha cabeçalhos específicos do gRPC.
  • Chama UseCors para adicionar o middleware CORS após a configuração de roteamento e antes da definição de pontos finais.
  • Especifica que o endpoints.MapGrpcService<GreeterService>() método suporta CORS com RequireCors.

gRPC-Web e streaming

O gRPC tradicional sobre HTTP/2 suporta cliente, servidor e streaming bidirecional. gRPC-Web oferece suporte limitado para streaming:

  • Os clientes de navegador do gRPC-Web não suportam chamadas de métodos de streaming do cliente e de streaming bidirecional.
  • Os clientes gRPC-Web .NET não suportam a utilização de métodos de client streaming e de transmissão bidirecional através de HTTP/1.1.
  • ASP.NET Os principais serviços gRPC hospedados no Serviço de Aplicativo do Azure e no IIS não oferecem suporte a streaming bidirecional.

Ao usar gRPC-Web, recomendamos apenas o uso de métodos unários e métodos de streaming de servidor.

Protocolo HTTP

O modelo de serviço gRPC ASP.NET Core, incluído no SDK do .NET, cria um aplicativo configurado apenas para HTTP/2. Este é um bom padrão quando um aplicativo suporta apenas gRPC tradicional sobre HTTP/2. gRPC-Web, no entanto, funciona com HTTP/1.1 e HTTP/2. Algumas plataformas, como UWP ou Unity, não podem usar HTTP/2. Para suportar todos os aplicativos cliente, configure o servidor para habilitar HTTP/1.1 e HTTP/2.

Atualize o protocolo padrão em appsettings.json:

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

Como alternativa, configure Kestrel endpoints no código de arranque.

Habilitar HTTP/1.1 e HTTP/2 na mesma porta requer TLS para negociação de protocolo. Para obter mais informações, consulte negociação do protocolo gRPC do ASP.NET Core.

Chame gRPC-Web a partir do navegador

As aplicações de navegador podem usar gRPC-Web para chamar serviços gRPC. Existem alguns requisitos e limitações ao chamar serviços gRPC com gRPC-Web a partir do navegador:

  • O servidor deve conter configuração para suportar gRPC-Web.
  • Streaming de cliente e chamadas de streaming bidirecionais não são suportados. O streaming do servidor é suportado.
  • Chamar serviços gRPC em um domínio diferente requer configuração CORS no servidor.

Cliente JavaScript gRPC-Web

Existe um cliente JavaScript gRPC-Web. Para obter instruções sobre como usar gRPC-Web a partir de JavaScript, consulte escrever código de cliente JavaScript com gRPC-Web.

Configurar gRPC-Web com o cliente gRPC .NET

O cliente gRPC .NET pode ser configurado para fazer chamadas gRPC-Web. Isso é útil para Blazor WebAssembly aplicativos, que são hospedados no navegador e têm as mesmas limitações HTTP do código JavaScript. Chamar gRPC-Web com um cliente .NET é o mesmo que HTTP/2 gRPC. A única modificação é como o canal é criado.

Para usar o gRPC-Web:

  • Adicione uma referência ao Grpc.Net.Client.Web pacote.
  • Verifique se a referência ao pacote é a Grpc.Net.Client versão 2.29.0 ou posterior.
  • Configure o canal para utilizar o 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" });

O código anterior:

  • Configura um canal para usar gRPC-Web.
  • Cria um cliente e faz uma chamada usando o canal.

GrpcWebHandler tem as seguintes opções de configuração:

  • InnerHandler: O componente básico HttpMessageHandler que realiza a solicitação HTTP do gRPC, por exemplo, HttpClientHandler.
  • GrpcWebMode: Um tipo de enumeração que especifica se a solicitação Content-Type HTTP gRPC é application/grpc-web ou application/grpc-web-text.
    • GrpcWebMode.GrpcWeb Configura o envio de conteúdo sem codificação. Valor padrão.
    • GrpcWebMode.GrpcWebText Configura o conteúdo codificado em Base64. Necessário para chamadas de streaming de servidor em navegadores.
  • HttpVersion: Protocolo Version HTTP usado para definir HttpRequestMessage.Version na solicitação HTTP gRPC subjacente. gRPC-Web não requer uma versão específica e não substitui o padrão, a menos que especificado.

Important

Os clientes gRPC gerados têm métodos síncronos e assíncronos para chamar métodos unários. Por exemplo, SayHello é síncrono e SayHelloAsync assíncrono. Métodos assíncronos são sempre necessários no Blazor WebAssembly. Chamar um método síncrono em um Blazor WebAssembly aplicativo faz com que o aplicativo pare de responder.

Utilize a fábrica de clientes gRPC com gRPC-Web

Crie um cliente .NET compatível com gRPC-Web usando a fábrica do cliente gRPC:

  • Adicione referências de pacote ao arquivo de projeto para os seguintes pacotes:
  • Registre um cliente gRPC com injeção de dependência (DI) usando o método de extensão genérico AddGrpcClient . Em um Blazor WebAssembly aplicativo, os serviços são registrados com DI em Program.cs.
  • Configure GrpcWebHandler usando o método de extensão ConfigurePrimaryHttpMessageHandler.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Para obter mais informações, consulte integração de fábrica do cliente gRPC no .NET.

Recursos adicionais

Saiba como configurar um serviço gRPC ASP.NET Core existente para ser chamável a partir de aplicativos do navegador, usando o protocolo gRPC-Web . O gRPC-Web permite que o JavaScript do navegador e Blazor os aplicativos chamem os serviços gRPC. Não é possível chamar um serviço gRPC HTTP/2 a partir de um aplicativo baseado em navegador. Os serviços gRPC hospedados no ASP.NET Core podem ser configurados para suportar gRPC-Web juntamente com HTTP/2 gRPC.

Para obter instruções sobre como adicionar um serviço gRPC a um aplicativo ASP.NET Core existente, consulte Adicionar serviços gRPC a um aplicativo ASP.NET Core.

Para obter instruções sobre como criar um projeto gRPC, consulte Criar um cliente e servidor gRPC .NET no ASP.NET Core.

ASP.NET Core gRPC-Web versus Envoy

Há duas opções de como adicionar gRPC-Web a um aplicativo ASP.NET Core:

  • Suporte gRPC-Web juntamente com gRPC HTTP/2 no ASP.NET Core. Esta opção usa middleware fornecido pelo Grpc.AspNetCore.Web pacote.
  • Utilize o suporte gRPC-Web do proxy Envoy para traduzir gRPC-Web para gRPC HTTP/2. A chamada traduzida é então encaminhada para o aplicativo ASP.NET Core.

Há prós e contras em cada abordagem. Se o ambiente de um aplicativo já estiver usando o Envoy como proxy, talvez faça sentido usar também o Envoy para fornecer suporte gRPC-Web. Para uma solução básica para gRPC-Web que requer apenas ASP.NET Core, Grpc.AspNetCore.Web é uma boa escolha.

Configurar o gRPC-Web no ASP.NET Core

Os serviços gRPC hospedados no ASP.NET Core podem ser configurados para suportar gRPC-Web juntamente com HTTP/2 gRPC. O gRPC-Web não requer alterações nos serviços. A única modificação é a configuração de inicialização.

Para habilitar o gRPC-Web com um serviço gRPC ASP.NET Core:

  • Adicione uma referência ao Grpc.AspNetCore.Web pacote.
  • Configure o aplicativo para usar gRPC-Web adicionando UseGrpcWeb e EnableGrpcWeb para 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();
    });
}

O código anterior:

  • Adiciona o middleware gRPC-Web, UseGrpcWeb, depois do roteamento e antes dos pontos de extremidade.
  • Especifica que o endpoints.MapGrpcService<GreeterService>() método suporta gRPC-Web com EnableGrpcWeb.

Como alternativa, o middleware gRPC-Web pode ser configurado para que todos os serviços suportem gRPC-Web por padrão e EnableGrpcWeb não seja necessário. Especifique new GrpcWebOptions { DefaultEnabled = true } quando o middleware é adicionado.

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

Note

Há um problema conhecido que faz com que o gRPC-Web falhe quando hospedado por HTTP.sys no .NET Core 3.x.

Uma solução alternativa para fazer com que o gRPC-Web funcione em HTTP.sys está disponível em Grpc-web experimental e UseHttpSys()? (grpc/grpc-dotnet #853).

gRPC-Web e CORS

A segurança do navegador impede que uma página da Web faça solicitações para um domínio diferente daquele que serviu a página da Web. Essa restrição se aplica a fazer chamadas gRPC-Web com aplicativos do navegador. Por exemplo, um aplicativo de navegador servido por https://www.contoso.com é impedido de chamar serviços gRPC-Web hospedados no https://services.contoso.com. O compartilhamento de recursos entre origens (CORS) pode ser usado para relaxar essa restrição.

Para permitir que um aplicativo de navegador faça chamadas gRPC-Web de origem cruzada, configure o CORS no ASP.NET Core. Utilize o suporte CORS interno e exponha cabeçalhos específicos do gRPC com 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");
    });
}

O código anterior:

  • Chama AddCors para adicionar serviços de CORS e configurar uma política de CORS que exponha cabeçalhos específicos do gRPC.
  • Chama UseCors para adicionar o middleware CORS após a configuração de roteamento e antes da definição de pontos finais.
  • Especifica que o endpoints.MapGrpcService<GreeterService>() método suporta CORS com RequireCors.

gRPC-Web e streaming

O gRPC tradicional sobre HTTP/2 suporta cliente, servidor e streaming bidirecional. gRPC-Web oferece suporte limitado para streaming:

  • Os clientes de navegador do gRPC-Web não suportam chamadas de métodos de streaming do cliente e de streaming bidirecional.
  • Os clientes gRPC-Web .NET não suportam a utilização de métodos de client streaming e de transmissão bidirecional através de HTTP/1.1.
  • ASP.NET Os principais serviços gRPC hospedados no Serviço de Aplicativo do Azure e no IIS não oferecem suporte a streaming bidirecional.

Ao usar gRPC-Web, recomendamos apenas o uso de métodos unários e métodos de streaming de servidor.

Protocolo HTTP

O modelo de serviço gRPC ASP.NET Core, incluído no SDK do .NET, cria um aplicativo configurado apenas para HTTP/2. Este é um bom padrão quando um aplicativo suporta apenas gRPC tradicional sobre HTTP/2. gRPC-Web, no entanto, funciona com HTTP/1.1 e HTTP/2. Algumas plataformas, como UWP ou Unity, não podem usar HTTP/2. Para suportar todos os aplicativos cliente, configure o servidor para habilitar HTTP/1.1 e HTTP/2.

Atualize o protocolo padrão em appsettings.json:

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

Como alternativa, configure Kestrel endpoints no código de arranque.

Habilitar HTTP/1.1 e HTTP/2 na mesma porta requer TLS para negociação de protocolo. Para obter mais informações, consulte negociação do protocolo gRPC do ASP.NET Core.

Chame gRPC-Web a partir do navegador

As aplicações de navegador podem usar gRPC-Web para chamar serviços gRPC. Existem alguns requisitos e limitações ao chamar serviços gRPC com gRPC-Web a partir do navegador:

  • O servidor deve conter configuração para suportar gRPC-Web.
  • Streaming de cliente e chamadas de streaming bidirecionais não são suportados. O streaming do servidor é suportado.
  • Chamar serviços gRPC em um domínio diferente requer configuração CORS no servidor.

Cliente JavaScript gRPC-Web

Existe um cliente JavaScript gRPC-Web. Para obter instruções sobre como usar gRPC-Web a partir de JavaScript, consulte escrever código de cliente JavaScript com gRPC-Web.

Configurar gRPC-Web com o cliente gRPC .NET

O cliente gRPC .NET pode ser configurado para fazer chamadas gRPC-Web. Isso é útil para Blazor WebAssembly aplicativos, que são hospedados no navegador e têm as mesmas limitações HTTP do código JavaScript. Chamar gRPC-Web com um cliente .NET é o mesmo que HTTP/2 gRPC. A única modificação é como o canal é criado.

Para usar o gRPC-Web:

  • Adicione uma referência ao Grpc.Net.Client.Web pacote.
  • Verifique se a referência ao pacote é a Grpc.Net.Client versão 2.29.0 ou posterior.
  • Configure o canal para utilizar o 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" });

O código anterior:

  • Configura um canal para usar gRPC-Web.
  • Cria um cliente e faz uma chamada usando o canal.

GrpcWebHandler tem as seguintes opções de configuração:

  • InnerHandler: O componente básico HttpMessageHandler que realiza a solicitação HTTP do gRPC, por exemplo, HttpClientHandler.
  • GrpcWebMode: Um tipo de enumeração que especifica se a solicitação Content-Type HTTP gRPC é application/grpc-web ou application/grpc-web-text.
    • GrpcWebMode.GrpcWeb Configura o envio de conteúdo sem codificação. Valor padrão.
    • GrpcWebMode.GrpcWebText Configura o conteúdo codificado em Base64. Necessário para chamadas de streaming de servidor em navegadores.
  • HttpVersion: Protocolo Version HTTP usado para definir HttpRequestMessage.Version na solicitação HTTP gRPC subjacente. gRPC-Web não requer uma versão específica e não substitui o padrão, a menos que especificado.

Important

Os clientes gRPC gerados têm métodos síncronos e assíncronos para chamar métodos unários. Por exemplo, SayHello é síncrono e SayHelloAsync assíncrono. Métodos assíncronos são sempre necessários no Blazor WebAssembly. Chamar um método síncrono em um Blazor WebAssembly aplicativo faz com que o aplicativo pare de responder.

Utilize a fábrica de clientes gRPC com gRPC-Web

Crie um cliente .NET compatível com gRPC-Web usando a fábrica do cliente gRPC:

  • Adicione referências de pacote ao arquivo de projeto para os seguintes pacotes:
  • Registre um cliente gRPC com injeção de dependência (DI) usando o método de extensão genérico AddGrpcClient . Em um Blazor WebAssembly aplicativo, os serviços são registrados com DI em Program.cs.
  • Configure GrpcWebHandler usando o método de extensão ConfigurePrimaryHttpMessageHandler.
builder.Services
    .AddGrpcClient<Greet.GreeterClient>(options =>
    {
        options.Address = new Uri("https://localhost:5001");
    })
    .ConfigurePrimaryHttpMessageHandler(
        () => new GrpcWebHandler(new HttpClientHandler()));

Para obter mais informações, consulte integração de fábrica do cliente gRPC no .NET.

Recursos adicionais