gRPC-Web em aplicativos gRPC no ASP.NET Core
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Saiba como configurar um serviço gRPC ASP.NET Core existente para ser chamado de aplicativos de navegador, usando o protocolo gRPC-Web. O gRPC-Web permite que o JavaScript do navegador e os aplicativos Blazor chamem serviços gRPC. Não é possível chamar um serviço gRPC HTTP/2 de um aplicativo baseado em navegador. Os serviços gRPC hospedados em ASP.NET Core podem ser configurados para dar suporte a gRPC-Web junto com HTTP/2 gRPC.
Para obter instruções sobre como adicionar um serviço gRPC a um aplicativo ASP.NET Core existente, confira Adicionar serviços gRPC a um aplicativo ASP.NET Core.
Para obter instruções sobre como criar um projeto gRPC, confira Criar um cliente e um servidor gRPC do .NET Core no ASP.NET Core.
ASP.NET Core gRPC-Web versus Envoy
Há duas opções para adicionar gRPC-Web a um aplicativo ASP.NET Core:
- Suporte a gRPC-Web junto com gRPC HTTP/2 em ASP.NET Core. Essa opção usa o middleware fornecido pelo pacote
Grpc.AspNetCore.Web
. - Use o suporte a gRPC-Web do proxy Envoy para converter gRPC-Web para gRPC HTTP/2. Em seguida, a chamada convertida é 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 também usar o Envoy para fornecer suporte a gRPC-Web. Para uma solução básica para gRPC-Web que requer apenas ASP.NET Core, Grpc.AspNetCore.Web
é uma boa opção.
Configurar gRPC-Web no ASP.NET Core
Os serviços gRPC hospedados em ASP.NET Core podem ser configurados para dar suporte a gRPC-Web junto com HTTP/2 gRPC. O gRPC-Web não exige nenhuma alteração 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 pacote
Grpc.AspNetCore.Web
. - Configure o aplicativo para usar gRPC-Web adicionando
UseGrpcWeb
eEnableGrpcWeb
aProgram.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
, após o roteamento e antes dos pontos de extremidade. - Especifica que o método
endpoints.MapGrpcService<GreeterService>()
dá suporte a gRPC-Web comEnableGrpcWeb
.
Como alternativa, o middleware gRPC-Web pode ser configurado para que todos os serviços ofereçam suporte a gRPC-Web por padrão e para que EnableGrpcWeb
não seja necessário. Especifique new GrpcWebOptions { DefaultEnabled = true }
quando o middleware for 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>().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();
Observação
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 no 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 ofereceu a página da Web. Essa restrição se aplica à realização de chamadas gRPC-Web com aplicativos de navegador. Por exemplo, um aplicativo de navegador oferecido por https://www.contoso.com
fica impedido de chamar serviços gRPC-Web hospedados em https://services.contoso.com
. O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para afrouxar essa restrição.
Para permitir que um aplicativo de navegador faça chamadas gRPC-Web entre origens, configure o CORS no ASP.NET Core. Use o suporte interno ao CORS 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");
}));
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 CORS e configurar uma política CORS que expõe cabeçalhos específicos ao gRPC. - Chama
UseCors
para adicionar o middleware CORS após a configuração de roteamento e antes da configuração dos pontos de extremidade. - Especifica que o método
endpoints.MapGrpcService<GreeterService>()
dá suporte a gRPC-Web comRequireCors
.
gRPC-Web e streaming
O gRPC tradicional por HTTP/2 dá suporte a streaming de cliente, servidor e bidirecional. O gRPC-Web oferece suporte limitado para streaming:
- Os clientes do navegador gRPC-Web não dão suporte à chamada de métodos de streaming de cliente e bidirecional.
- Os clientes .NET de gRPC-Web não dão suporte à chamada de métodos de streaming de cliente e bidirecional sobre HTTP/1.1.
- ASP.NET Core serviços gRPC hospedados no Serviço de Aplicativo do Azure e o IIS não dão suporte ao 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 do ASP.NET Core, incluído no SDK do .NET, cria um aplicativo configurado apenas para HTTP/2. Isso é um bom padrão quando um aplicativo dá suporte apenas ao gRPC tradicional por HTTP/2. O 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 dar suporte a 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 pontos de extremidade Kestrel no código de inicialização.
A habilitação de HTTP/1.1 e HTTP/2 na mesma porta exige TLS para negociação de protocolo. Para obter mais informações, confira Negociação de protocolo gRPC do ASP.NET Core.
Chamar gRPC-Web do navegador
Os aplicativos de navegador podem usar gRPC-Web para chamar serviços gRPC. Há alguns requisitos e limitações ao chamar serviços gRPC com gRPC-Web do navegador:
- O servidor deve conter a configuração para dar suporte a gRPC-Web.
- Não há suporte para chamadas a streaming de cliente e bidirecional. Há suporte para streaming de servidor.
- Para chamar serviços gRPC em um domínio diferente, você precisa da configuração de CORS no servidor.
Cliente gRPC-Web em JavaScript
Há um cliente gRPC-Web em JavaScript. Para obter instruções sobre como usar gRPC-Web em JavaScript, confira Escrever código de cliente em JavaScript com gRPC-Web.
Configurar gRPC-Web com o cliente gRPC de .NET
O cliente gRPC de .NET pode ser configurado para fazer chamadas a gRPC-Web. Isso é útil para aplicativos Blazor WebAssembly, que são hospedados no navegador e têm as mesmas limitações de 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 gRPC-Web:
- Adicione uma referência ao pacote
Grpc.Net.Client.Web
. - Verifique se a referência ao pacote
Grpc.Net.Client
é a versão 2.29.0 ou posterior. - Configure o canal para usar 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 HttpMessageHandler subjacente que faz a solicitação HTTP gRPC, por exemplo,HttpClientHandler
.GrpcWebMode
: um tipo de enumeração que especifica se a solicitação HTTP gRPCContent-Type
éapplication/grpc-web
ouapplication/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 HTTPVersion
usado para definir HttpRequestMessage.Version na solicitação HTTP do gRPC subjacente. O gRPC-Web não requer uma versão específica e não substitui o padrão, a menos que especificado.
Importante
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 em Blazor WebAssembly. Chamar um método síncrono em um aplicativo Blazor WebAssembly faz com que o aplicativo fique sem resposta.
Usar a fábrica de clientes gRPC com gRPC-Web
Crie um cliente .NET compatível com gRPC-Web usando a fábrica de clientes gRPC:
- Adicione referências de pacote ao arquivo de projeto para os seguintes pacotes:
- Registre um cliente gRPC com DI (injeção de dependência) usando o método de extensão genérico
AddGrpcClient
. Em um aplicativo Blazor WebAssembly, os serviços são registrados com DI noProgram.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 saber mais, confira 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 chamado de aplicativos de navegador, usando o protocolo gRPC-Web. O gRPC-Web permite que o JavaScript do navegador e os aplicativos Blazor chamem serviços gRPC. Não é possível chamar um serviço gRPC HTTP/2 de um aplicativo baseado em navegador. Os serviços gRPC hospedados em ASP.NET Core podem ser configurados para dar suporte a gRPC-Web junto com HTTP/2 gRPC.
Para obter instruções sobre como adicionar um serviço gRPC a um aplicativo ASP.NET Core existente, confira Adicionar serviços gRPC a um aplicativo ASP.NET Core.
Para obter instruções sobre como criar um projeto gRPC, confira Criar um cliente e um servidor gRPC do .NET Core no ASP.NET Core.
ASP.NET Core gRPC-Web versus Envoy
Há duas opções para adicionar gRPC-Web a um aplicativo ASP.NET Core:
- Suporte a gRPC-Web junto com gRPC HTTP/2 em ASP.NET Core. Essa opção usa o middleware fornecido pelo pacote
Grpc.AspNetCore.Web
. - Use o suporte a gRPC-Web do proxy Envoy para converter gRPC-Web para gRPC HTTP/2. Em seguida, a chamada convertida é 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 também usar o Envoy para fornecer suporte a gRPC-Web. Para uma solução básica para gRPC-Web que requer apenas ASP.NET Core, Grpc.AspNetCore.Web
é uma boa opção.
Configurar gRPC-Web no ASP.NET Core
Os serviços gRPC hospedados em ASP.NET Core podem ser configurados para dar suporte a gRPC-Web junto com HTTP/2 gRPC. O gRPC-Web não exige nenhuma alteração 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 pacote
Grpc.AspNetCore.Web
. - Configure o aplicativo para usar gRPC-Web adicionando
UseGrpcWeb
eEnableGrpcWeb
aProgram.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
, após o roteamento e antes dos pontos de extremidade. - Especifica que o método
endpoints.MapGrpcService<GreeterService>()
dá suporte a gRPC-Web comEnableGrpcWeb
.
Como alternativa, o middleware gRPC-Web pode ser configurado para que todos os serviços ofereçam suporte a gRPC-Web por padrão e para que EnableGrpcWeb
não seja necessário. Especifique new GrpcWebOptions { DefaultEnabled = true }
quando o middleware for 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>().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();
Observação
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 no 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 ofereceu a página da Web. Essa restrição se aplica à realização de chamadas gRPC-Web com aplicativos de navegador. Por exemplo, um aplicativo de navegador oferecido por https://www.contoso.com
fica impedido de chamar serviços gRPC-Web hospedados em https://services.contoso.com
. O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para afrouxar essa restrição.
Para permitir que um aplicativo de navegador faça chamadas gRPC-Web entre origens, configure o CORS no ASP.NET Core. Use o suporte interno ao CORS 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");
}));
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 CORS e configurar uma política CORS que expõe cabeçalhos específicos ao gRPC. - Chama
UseCors
para adicionar o middleware CORS após a configuração de roteamento e antes da configuração dos pontos de extremidade. - Especifica que o método
endpoints.MapGrpcService<GreeterService>()
dá suporte a gRPC-Web comRequireCors
.
gRPC-Web e streaming
O gRPC tradicional por HTTP/2 dá suporte a streaming de cliente, servidor e bidirecional. O gRPC-Web oferece suporte limitado para streaming:
- Os clientes do navegador gRPC-Web não dão suporte à chamada de métodos de streaming de cliente e bidirecional.
- Os clientes .NET de gRPC-Web não dão suporte à chamada de métodos de streaming de cliente e bidirecional sobre HTTP/1.1.
- ASP.NET Core serviços gRPC hospedados no Serviço de Aplicativo do Azure e o IIS não dão suporte ao 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 do ASP.NET Core, incluído no SDK do .NET, cria um aplicativo configurado apenas para HTTP/2. Isso é um bom padrão quando um aplicativo dá suporte apenas ao gRPC tradicional por HTTP/2. O 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 dar suporte a 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 pontos de extremidade Kestrel no código de inicialização.
A habilitação de HTTP/1.1 e HTTP/2 na mesma porta exige TLS para negociação de protocolo. Para obter mais informações, confira Negociação de protocolo gRPC do ASP.NET Core.
Chamar gRPC-Web do navegador
Os aplicativos de navegador podem usar gRPC-Web para chamar serviços gRPC. Há alguns requisitos e limitações ao chamar serviços gRPC com gRPC-Web do navegador:
- O servidor deve conter a configuração para dar suporte a gRPC-Web.
- Não há suporte para chamadas a streaming de cliente e bidirecional. Há suporte para streaming de servidor.
- Para chamar serviços gRPC em um domínio diferente, você precisa da configuração de CORS no servidor.
Cliente gRPC-Web em JavaScript
Há um cliente gRPC-Web em JavaScript. Para obter instruções sobre como usar gRPC-Web em JavaScript, confira Escrever código de cliente em JavaScript com gRPC-Web.
Configurar gRPC-Web com o cliente gRPC de .NET
O cliente gRPC de .NET pode ser configurado para fazer chamadas a gRPC-Web. Isso é útil para aplicativos Blazor WebAssembly, que são hospedados no navegador e têm as mesmas limitações de 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 gRPC-Web:
- Adicione uma referência ao pacote
Grpc.Net.Client.Web
. - Verifique se a referência ao pacote
Grpc.Net.Client
é a versão 2.29.0 ou posterior. - Configure o canal para usar 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 HttpMessageHandler subjacente que faz a solicitação HTTP gRPC, por exemplo,HttpClientHandler
.GrpcWebMode
: um tipo de enumeração que especifica se a solicitação HTTP gRPCContent-Type
éapplication/grpc-web
ouapplication/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 HTTPVersion
usado para definir HttpRequestMessage.Version na solicitação HTTP do gRPC subjacente. O gRPC-Web não requer uma versão específica e não substitui o padrão, a menos que especificado.
Importante
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 em Blazor WebAssembly. Chamar um método síncrono em um aplicativo Blazor WebAssembly faz com que o aplicativo fique sem resposta.
Usar a fábrica de clientes gRPC com gRPC-Web
Crie um cliente .NET compatível com gRPC-Web usando a fábrica de clientes gRPC:
- Adicione referências de pacote ao arquivo de projeto para os seguintes pacotes:
- Registre um cliente gRPC com DI (injeção de dependência) usando o método de extensão genérico
AddGrpcClient
. Em um aplicativo Blazor WebAssembly, os serviços são registrados com DI noProgram.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 saber mais, confira 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 chamado de aplicativos de navegador, usando o protocolo gRPC-Web. O gRPC-Web permite que o JavaScript do navegador e os aplicativos Blazor chamem serviços gRPC. Não é possível chamar um serviço gRPC HTTP/2 de um aplicativo baseado em navegador. Os serviços gRPC hospedados em ASP.NET Core podem ser configurados para dar suporte a gRPC-Web junto com HTTP/2 gRPC.
Para obter instruções sobre como adicionar um serviço gRPC a um aplicativo ASP.NET Core existente, confira Adicionar serviços gRPC a um aplicativo ASP.NET Core.
Para obter instruções sobre como criar um projeto gRPC, confira Criar um cliente e um servidor gRPC do .NET Core no ASP.NET Core.
ASP.NET Core gRPC-Web versus Envoy
Há duas opções para adicionar gRPC-Web a um aplicativo ASP.NET Core:
- Suporte a gRPC-Web junto com gRPC HTTP/2 em ASP.NET Core. Essa opção usa o middleware fornecido pelo pacote
Grpc.AspNetCore.Web
. - Use o suporte a gRPC-Web do proxy Envoy para converter gRPC-Web para gRPC HTTP/2. Em seguida, a chamada convertida é 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 também usar o Envoy para fornecer suporte a gRPC-Web. Para uma solução básica para gRPC-Web que requer apenas ASP.NET Core, Grpc.AspNetCore.Web
é uma boa opção.
Configurar gRPC-Web no ASP.NET Core
Os serviços gRPC hospedados em ASP.NET Core podem ser configurados para dar suporte a gRPC-Web junto com HTTP/2 gRPC. O gRPC-Web não exige nenhuma alteração 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 pacote
Grpc.AspNetCore.Web
. - Configure o aplicativo para usar gRPC-Web adicionando
UseGrpcWeb
eEnableGrpcWeb
aStartup.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
, após o roteamento e antes dos pontos de extremidade. - Especifica que o método
endpoints.MapGrpcService<GreeterService>()
dá suporte a gRPC-Web comEnableGrpcWeb
.
Como alternativa, o middleware gRPC-Web pode ser configurado para que todos os serviços ofereçam suporte a gRPC-Web por padrão e para que EnableGrpcWeb
não seja necessário. Especifique new GrpcWebOptions { DefaultEnabled = true }
quando o middleware for 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>();
});
}
}
Observação
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 no 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 ofereceu a página da Web. Essa restrição se aplica à realização de chamadas gRPC-Web com aplicativos de navegador. Por exemplo, um aplicativo de navegador oferecido por https://www.contoso.com
fica impedido de chamar serviços gRPC-Web hospedados em https://services.contoso.com
. O CORS (Compartilhamento de Recursos entre Origens) pode ser usado para afrouxar essa restrição.
Para permitir que um aplicativo de navegador faça chamadas gRPC-Web entre origens, configure o CORS no ASP.NET Core. Use o suporte interno ao CORS 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 CORS e configurar uma política CORS que expõe cabeçalhos específicos ao gRPC. - Chama
UseCors
para adicionar o middleware CORS após a configuração de roteamento e antes da configuração dos pontos de extremidade. - Especifica que o método
endpoints.MapGrpcService<GreeterService>()
dá suporte a gRPC-Web comRequireCors
.
gRPC-Web e streaming
O gRPC tradicional por HTTP/2 dá suporte a streaming de cliente, servidor e bidirecional. O gRPC-Web oferece suporte limitado para streaming:
- Os clientes do navegador gRPC-Web não dão suporte à chamada de métodos de streaming de cliente e bidirecional.
- Os clientes .NET de gRPC-Web não dão suporte à chamada de métodos de streaming de cliente e bidirecional sobre HTTP/1.1.
- ASP.NET Core serviços gRPC hospedados no Serviço de Aplicativo do Azure e o IIS não dão suporte ao 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 do ASP.NET Core, incluído no SDK do .NET, cria um aplicativo configurado apenas para HTTP/2. Isso é um bom padrão quando um aplicativo dá suporte apenas ao gRPC tradicional por HTTP/2. O 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 dar suporte a 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 pontos de extremidade Kestrel no código de inicialização.
A habilitação de HTTP/1.1 e HTTP/2 na mesma porta exige TLS para negociação de protocolo. Para obter mais informações, confira Negociação de protocolo gRPC do ASP.NET Core.
Chamar gRPC-Web do navegador
Os aplicativos de navegador podem usar gRPC-Web para chamar serviços gRPC. Há alguns requisitos e limitações ao chamar serviços gRPC com gRPC-Web do navegador:
- O servidor deve conter a configuração para dar suporte a gRPC-Web.
- Não há suporte para chamadas a streaming de cliente e bidirecional. Há suporte para streaming de servidor.
- Para chamar serviços gRPC em um domínio diferente, você precisa da configuração de CORS no servidor.
Cliente gRPC-Web em JavaScript
Há um cliente gRPC-Web em JavaScript. Para obter instruções sobre como usar gRPC-Web em JavaScript, confira Escrever código de cliente em JavaScript com gRPC-Web.
Configurar gRPC-Web com o cliente gRPC de .NET
O cliente gRPC de .NET pode ser configurado para fazer chamadas a gRPC-Web. Isso é útil para aplicativos Blazor WebAssembly, que são hospedados no navegador e têm as mesmas limitações de 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 gRPC-Web:
- Adicione uma referência ao pacote
Grpc.Net.Client.Web
. - Verifique se a referência ao pacote
Grpc.Net.Client
é a versão 2.29.0 ou posterior. - Configure o canal para usar 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 HttpMessageHandler subjacente que faz a solicitação HTTP gRPC, por exemplo,HttpClientHandler
.GrpcWebMode
: um tipo de enumeração que especifica se a solicitação HTTP gRPCContent-Type
éapplication/grpc-web
ouapplication/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 HTTPVersion
usado para definir HttpRequestMessage.Version na solicitação HTTP do gRPC subjacente. O gRPC-Web não requer uma versão específica e não substitui o padrão, a menos que especificado.
Importante
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 em Blazor WebAssembly. Chamar um método síncrono em um aplicativo Blazor WebAssembly faz com que o aplicativo fique sem resposta.
Usar a fábrica de clientes gRPC com gRPC-Web
Crie um cliente .NET compatível com gRPC-Web usando a fábrica de clientes gRPC:
- Adicione referências de pacote ao arquivo de projeto para os seguintes pacotes:
- Registre um cliente gRPC com DI (injeção de dependência) usando o método de extensão genérico
AddGrpcClient
. Em um aplicativo Blazor WebAssembly, os serviços são registrados com DI noProgram.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 saber mais, confira Integração de fábrica do cliente gRPC no .NET.