Solucionar problemas do gRPC no .NET CoreTroubleshoot gRPC on .NET Core

Por James Newton – KingBy James Newton-King

Este documento aborda problemas comumente encontrados ao desenvolver aplicativos gRPC no .NET.This document discusses commonly encountered problems when developing gRPC apps on .NET.

Incompatibilidade entre a configuração de SSL/TLS do cliente e do serviçoMismatch between client and service SSL/TLS configuration

O modelo gRPC e os exemplos usam o protocolo TLS para proteger os serviços do gRPC por padrão.The gRPC template and samples use Transport Layer Security (TLS) to secure gRPC services by default. Os clientes gRPC precisam usar uma conexão segura para chamar os serviços gRPC protegidos com êxito.gRPC clients need to use a secure connection to call secured gRPC services successfully.

Você pode verificar se o serviço gRPC do ASP.NET Core está usando o TLS nos logs gravados no início do aplicativo.You can verify the ASP.NET Core gRPC service is using TLS in the logs written on app start. O serviço escutará em um ponto de extremidade HTTPS:The service will be listening on an HTTPS endpoint:

info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development

O cliente .NET Core deve usar https no endereço do servidor para fazer chamadas com uma conexão segura:The .NET Core client must use https in the server address to make calls with a secured connection:

static async Task Main(string[] args)
{
    // The port number(5001) must match the port of the gRPC server.
    var channel = GrpcChannel.ForAddress("https://localhost:5001");
    var client = new Greet.GreeterClient(channel);
}

Todas as implementações de cliente do gRPC dão suporte a TLS.All gRPC client implementations support TLS. Os clientes gRPC de outras linguagens normalmente exigem o canal configurado com o SslCredentials .gRPC clients from other languages typically require the channel configured with SslCredentials. SslCredentials Especifica o certificado que o cliente usará e deve ser usado em vez de credenciais não seguras.SslCredentials specifies the certificate that the client will use, and it must be used instead of insecure credentials. Para obter exemplos de como configurar as diferentes implementações de cliente gRPC para usar o TLS, consulte autenticação do gRPC.For examples of configuring the different gRPC client implementations to use TLS, see gRPC Authentication.

Chamar um serviço gRPC com um certificado não confiável/inválidoCall a gRPC service with an untrusted/invalid certificate

O cliente .NET gRPC requer que o serviço tenha um certificado confiável.The .NET gRPC client requires the service to have a trusted certificate. A seguinte mensagem de erro é retornada ao chamar um serviço gRPC sem um certificado confiável:The following error message is returned when calling a gRPC service without a trusted certificate:

Exceção sem tratamento.Unhandled exception. Sistema .net. http. HttpRequestexception: não foi possível estabelecer a conexão SSL, consulte a exceção interna.System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: o certificado remoto é inválido de acordo com o procedimento de validação.---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

Você poderá ver esse erro se estiver testando seu aplicativo localmente e o ASP.NET Core certificado de desenvolvimento HTTPS não for confiável.You may see this error if you are testing your app locally and the ASP.NET Core HTTPS development certificate is not trusted. Para obter instruções sobre como corrigir esse problema, confira Confiar no certificado de desenvolvimento HTTPS do ASP.NET Core no Windows e no macOS.For instructions to fix this issue, see Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.

Se você estiver chamando um serviço gRPC em outro computador e não puder confiar no certificado, o cliente gRPC poderá ser configurado para ignorar o certificado inválido.If you are calling a gRPC service on another machine and are unable to trust the certificate then the gRPC client can be configured to ignore the invalid certificate. O código a seguir usa HttpClientHandler. ServerCertificateCustomValidationCallback para permitir chamadas sem um certificado confiável:The following code uses HttpClientHandler.ServerCertificateCustomValidationCallback to allow calls without a trusted certificate:

var httpHandler = new HttpClientHandler();
// Return `true` to allow certificates that are untrusted/invalid
httpHandler.ServerCertificateCustomValidationCallback = 
    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

var channel = GrpcChannel.ForAddress("https://localhost:5001",
    new GrpcChannelOptions { HttpHandler = httpHandler });
var client = new Greet.GreeterClient(channel);

Aviso

Certificados não confiáveis só devem ser usados durante o desenvolvimento do aplicativo.Untrusted certificates should only be used during app development. Os aplicativos de produção sempre devem usar certificados válidos.Production apps should always use valid certificates.

Chamar serviços gRPCs inseguros com o cliente .NET CoreCall insecure gRPC services with .NET Core client

Quando um aplicativo está usando o .NET Core 3. x, é necessária configuração adicional para chamar serviços gRPCs inseguros com o cliente .NET Core.When an app is using .NET Core 3.x, additional configuration is required to call insecure gRPC services with the .NET Core client. O cliente gRPC deve definir o System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport comutador para true e usar http no endereço do servidor:The gRPC client must set the System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport switch to true and use http in the server address:

// This switch must be set before creating the GrpcChannel/HttpClient.
AppContext.SetSwitch(
    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

// The port number(5000) must match the port of the gRPC server.
var channel = GrpcChannel.ForAddress("http://localhost:5000");
var client = new Greet.GreeterClient(channel);

Os aplicativos .NET 5 não precisam de configuração adicional, mas para chamar serviços gRPCs inseguros eles devem usar a Grpc.Net.Client versão 2.32.0 ou posterior..NET 5 apps don't need additional configuration, but to call insecure gRPC services they must use Grpc.Net.Client version 2.32.0 or later.

Não é possível iniciar o aplicativo ASP.NET Core gRPC no macOSUnable to start ASP.NET Core gRPC app on macOS

O Kestrel não dá suporte a HTTP/2 com TLS no macOS e versões mais antigas do Windows, como o Windows 7.Kestrel doesn't support HTTP/2 with TLS on macOS and older Windows versions such as Windows 7. O modelo ASP.NET Core gRPC e os exemplos usam TLS por padrão.The ASP.NET Core gRPC template and samples use TLS by default. Você verá a seguinte mensagem de erro ao tentar iniciar o servidor gRPC:You'll see the following error message when you attempt to start the gRPC server:

Não é possível associar ao https://localhost:5001 na interface de loopback IPv4: ' http/2 sobre TLS não tem suporte no MacOS devido ao suporte de ALPN ausente. '.Unable to bind to https://localhost:5001 on the IPv4 loopback interface: 'HTTP/2 over TLS is not supported on macOS due to missing ALPN support.'.

Para contornar esse problema, configure o Kestrel e o cliente gRPC para usar HTTP/2 sem TLS.To work around this issue, configure Kestrel and the gRPC client to use HTTP/2 without TLS. Você só deve fazer isso durante o desenvolvimento.You should only do this during development. Não usar o TLS fará com que as mensagens gRPC sejam enviadas sem criptografia.Not using TLS will result in gRPC messages being sent without encryption.

Kestrel deve configurar um ponto de extremidade HTTP/2 sem TLS em Program.cs:Kestrel must configure an HTTP/2 endpoint without TLS in Program.cs:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.ConfigureKestrel(options =>
            {
                // Setup a HTTP/2 endpoint without TLS.
                options.ListenLocalhost(5000, o => o.Protocols = 
                    HttpProtocols.Http2);
            });
            webBuilder.UseStartup<Startup>();
        });

Quando um ponto de extremidade HTTP/2 é configurado sem TLS, o ListenerOptions do ponto de extremidade deve ser definido como HttpProtocols.Http2 .When an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. HttpProtocols.Http1AndHttp2 Não pode ser usado porque o TLS é necessário para negociar HTTP/2.HttpProtocols.Http1AndHttp2 can't be used because TLS is required to negotiate HTTP/2. Sem o TLS, todas as conexões com o ponto de extremidade padrão para HTTP/1.1 e chamadas gRPC falham.Without TLS, all connections to the endpoint default to HTTP/1.1, and gRPC calls fail.

Quando um ponto de extremidade HTTP/2 é configurado sem TLS, o ListenerOptions do ponto de extremidade deve ser definido como HttpProtocols.Http2 .When an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. HttpProtocols.Http1AndHttp2 Não pode ser usado porque o TLS é necessário para negociar HTTP/2.HttpProtocols.Http1AndHttp2 can't be used because TLS is required to negotiate HTTP/2. Sem o TLS, todas as conexões com o ponto de extremidade padrão para HTTP/1.1 e chamadas gRPC falham.Without TLS, all connections to the endpoint default to HTTP/1.1, and gRPC calls fail.

O cliente gRPC também deve ser configurado para não usar o TLS.The gRPC client must also be configured to not use TLS. Para obter mais informações, consulte chamar serviços gRPCs inseguros com o cliente .NET Core.For more information, see Call insecure gRPC services with .NET Core client.

Aviso

O HTTP/2 sem TLS só deve ser usado durante o desenvolvimento do aplicativo.HTTP/2 without TLS should only be used during app development. Os aplicativos de produção sempre devem usar a segurança de transporte.Production apps should always use transport security. Para obter mais informações, consulte Security Considerations in gRPC for ASP.NET Core.For more information, see Security considerations in gRPC for ASP.NET Core.

os ativos do C# gRPC não são gerados pelo código de arquivos. protogRPC C# assets are not code generated from .proto files

a geração de código gRPC de clientes concretos e classes base de serviço requer que os arquivos e as ferramentas do protobuf sejam referenciados de um projeto.gRPC code generation of concrete clients and service base classes requires protobuf files and tooling to be referenced from a project. Você deve incluir:You must include:

  • arquivos . proto que você deseja usar no <Protobuf> grupo de itens..proto files you want to use in the <Protobuf> item group. Arquivos . proto importados devem ser referenciados pelo projeto.Imported .proto files must be referenced by the project.
  • Referência de pacote para o pacote de ferramentas do gRPC gRPC. Tools.Package reference to the gRPC tooling package Grpc.Tools.

Para obter mais informações sobre como gerar ativos do gRPC C#, consulte Serviços do gRPC com C# .For more information on generating gRPC C# assets, see Serviços do gRPC com C#.

Um ASP.NET Core aplicativo Web que hospeda serviços gRPCs precisa apenas da classe base de serviço gerada:An ASP.NET Core web app hosting gRPC services only needs the service base class generated:

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>

Um aplicativo cliente gRPC que faz chamadas gRPC precisa apenas do cliente concreto gerado:A gRPC client app making gRPC calls only needs the concrete client generated:

<ItemGroup>
  <Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>

Projetos do WPF não podem gerar ativos gRPC C# a partir de arquivos. protoWPF projects unable to generate gRPC C# assets from .proto files

Os projetos do WPF têm um problema conhecido que impede a geração de código gRPC de funcionar corretamente.WPF projects have a known issue that prevents gRPC code generation from working correctly. Quaisquer tipos de gRPC gerados em um projeto do WPF referenciando Grpc.Tools e . proto arquivos criarão erros de compilação quando usados:Any gRPC types generated in a WPF project by referencing Grpc.Tools and .proto files will create compilation errors when used:

erro CS0246: não foi possível encontrar o nome do namespace ou tipo ' MyGrpcServices ' (está faltando uma diretiva using ou uma referência de assembly?)error CS0246: The type or namespace name 'MyGrpcServices' could not be found (are you missing a using directive or an assembly reference?)

Você pode solucionar esse problema:You can workaround this issue by:

  1. Crie um novo projeto de biblioteca de classes do .NET Core.Create a new .NET Core class library project.
  2. No novo projeto, adicione referências para habilitar a geração de código C# a partir de arquivos * . proto:In the new project, add references to enable C# code generation from *.proto files:
    • Adicione uma referência de pacote ao pacote Grpc. Tools .Add a package reference to Grpc.Tools package.
    • Adicione arquivos * . proto ao <Protobuf> grupo de itens.Add *.proto files to the <Protobuf> item group.
  3. No aplicativo do WPF, adicione uma referência ao novo projeto.In the WPF application, add a reference to the new project.

O aplicativo WPF pode usar os tipos gerados gRPC do novo projeto de biblioteca de classes.The WPF application can use the gRPC generated types from the new class library project.

Aviso

ASP.NET Core gRPC tem requisitos adicionais para serem usados com Azure app serviço ou o IIS.ASP.NET Core gRPC has extra requirements for being used with Azure App Service or IIS. Para obter mais informações sobre onde gRPC pode ser usado, consulte gRPC em plataformas com suporte do .NET .For more information on where gRPC can be used, see gRPC em plataformas com suporte do .NET.