Rozwiązywanie problemów z gRPC na platformie .NET CoreTroubleshoot gRPC on .NET Core

Przez Kuba Kowalski-królaBy James Newton-King

W tym dokumencie omówiono często występujące problemy podczas tworzenia aplikacji gRPC na platformie .NET.This document discusses commonly encountered problems when developing gRPC apps on .NET.

Niezgodność między konfiguracją protokołu SSL klienta i usługi TLSMismatch between client and service SSL/TLS configuration

Szablon gRPC i przykłady używają usługi Transport Layer Security (TLS) do domyślnego zabezpieczania usług gRPC.The gRPC template and samples use Transport Layer Security (TLS) to secure gRPC services by default. Klienci gRPC muszą używać bezpiecznego połączenia w celu pomyślnego wywołania zabezpieczonych usług gRPC.gRPC clients need to use a secure connection to call secured gRPC services successfully.

Możesz sprawdzić, ASP.NET Core usługa gRPC korzysta z protokołu TLS w dziennikach, które zostały zapisane podczas uruchamiania aplikacji.You can verify the ASP.NET Core gRPC service is using TLS in the logs written on app start. Usługa nasłuchuje na punkcie końcowym 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

Aby umożliwić nawiązywanie połączeń z bezpiecznym połączeniem, klient .NET Core musi użyć https adresu serwera: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);
}

Wszystkie implementacje klienta gRPC obsługują protokół TLS.All gRPC client implementations support TLS. Klienci gRPC z innych języków zwykle wymagają kanału skonfigurowanego z SslCredentials .gRPC clients from other languages typically require the channel configured with SslCredentials. SslCredentials Określa certyfikat, który będzie używany przez klienta i musi być używany zamiast niezabezpieczonych poświadczeń.SslCredentials specifies the certificate that the client will use, and it must be used instead of insecure credentials. Przykłady konfigurowania różnych implementacji klienta gRPC do korzystania z protokołu TLS można znaleźć w temacie GRPC Authentication (uwierzytelnianie).For examples of configuring the different gRPC client implementations to use TLS, see gRPC Authentication.

Wywołaj usługę gRPC z niezaufanym/nieprawidłowym certyfikatemCall a gRPC service with an untrusted/invalid certificate

Klient .NET gRPC wymaga, aby usługa miała zaufany certyfikat.The .NET gRPC client requires the service to have a trusted certificate. Podczas wywoływania usługi gRPC bez zaufanego certyfikatu zwracany jest następujący komunikat o błędzie:The following error message is returned when calling a gRPC service without a trusted certificate:

Nieobsługiwany wyjątek.Unhandled exception. System .NET. http. HttpRequestexception: nie można nawiązać połączenia SSL, zobacz wyjątek wewnętrzny.System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> system. Security. Authentication. AuthenticationException: certyfikat zdalny jest nieprawidłowy zgodnie z procedurą walidacji.---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

Ten błąd może pojawić się, jeśli testujesz aplikację lokalnie, a ASP.NET Core certyfikat programistyczny HTTPS nie jest zaufany.You may see this error if you are testing your app locally and the ASP.NET Core HTTPS development certificate is not trusted. Aby uzyskać instrukcje dotyczące rozwiązania tego problemu, zobacz temat ASP.NET Core ufanie certyfikatowi Deweloperskiemu protokołu HTTPS w systemie Windows i macOS.For instructions to fix this issue, see Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.

Jeśli wywołujesz usługę gRPC na innym komputerze i nie można ufać certyfikatowi, można skonfigurować klienta gRPC do ignorowania nieprawidłowego certyfikatu.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. Poniższy kod używa metody HttpClientHandler. ServerCertificateCustomValidationCallback , aby zezwalać na wywołania bez zaufanego certyfikatu: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);

Ostrzeżenie

Niezaufanych certyfikatów należy używać tylko podczas opracowywania aplikacji.Untrusted certificates should only be used during app development. Aplikacje produkcyjne powinny zawsze używać prawidłowych certyfikatów.Production apps should always use valid certificates.

Wywoływanie niezabezpieczonych usług gRPC z klientem .NET CoreCall insecure gRPC services with .NET Core client

Gdy aplikacja korzysta z platformy .NET Core 3. x, wymagana jest dodatkowa konfiguracja do wywoływania niezabezpieczonych usług gRPC z klientem .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. Klient gRPC musi ustawić System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport przełącznik do true i używać http go w adresie serwera: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);

Aplikacje .NET 5 nie potrzebują dodatkowej konfiguracji, ale w celu wywołania niezabezpieczonych usług gRPC muszą używać Grpc.Net.Client wersji 2.32.0 lub nowszej..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.

Nie można uruchomić aplikacji ASP.NET Core gRPC na macOSUnable to start ASP.NET Core gRPC app on macOS

Kestrel nie obsługuje protokołu HTTP/2 z protokołem TLS w macOS i starszych wersjach systemu Windows, takich jak Windows 7.Kestrel doesn't support HTTP/2 with TLS on macOS and older Windows versions such as Windows 7. ASP.NET Core szablon i przykłady gRPC domyślnie korzystają z protokołu TLS.The ASP.NET Core gRPC template and samples use TLS by default. Podczas próby uruchomienia serwera gRPC zobaczysz następujący komunikat o błędzie:You'll see the following error message when you attempt to start the gRPC server:

Nie można utworzyć powiązania z https://localhost:5001 interfejsem sprzężenia zwrotnego IPv4: "http/2 za pośrednictwem protokołu TLS nie jest obsługiwane w macOS ze względu na brak pomocy technicznej ClientHello alpn".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.'.

Aby obejść ten problem, należy skonfigurować Kestrel i klienta gRPC do używania protokołu HTTP/2 bez szyfrowania TLS.To work around this issue, configure Kestrel and the gRPC client to use HTTP/2 without TLS. Należy to zrobić tylko podczas projektowania.You should only do this during development. Użycie protokołu TLS spowoduje, że komunikaty gRPC są wysyłane bez szyfrowania.Not using TLS will result in gRPC messages being sent without encryption.

Kestrel musi skonfigurować punkt końcowy HTTP/2 bez protokołu TLS w 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>();
        });

Gdy punkt końcowy protokołu HTTP/2 jest skonfigurowany bez protokołu TLS, ListenOptions. protokoły punktu końcowego muszą mieć ustawioną wartość HttpProtocols.Http2 .When an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. HttpProtocols.Http1AndHttp2 nie można użyć, ponieważ protokół TLS jest wymagany do negocjowania protokołu HTTP/2.HttpProtocols.Http1AndHttp2 can't be used because TLS is required to negotiate HTTP/2. Bez protokołu TLS wszystkie połączenia z punktem końcowym domyślne do protokołu HTTP/1.1 i wywołania gRPC kończą się niepowodzeniem.Without TLS, all connections to the endpoint default to HTTP/1.1, and gRPC calls fail.

Gdy punkt końcowy protokołu HTTP/2 jest skonfigurowany bez protokołu TLS, ListenOptions. protokoły punktu końcowego muszą mieć ustawioną wartość HttpProtocols.Http2 .When an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. HttpProtocols.Http1AndHttp2 nie można użyć, ponieważ protokół TLS jest wymagany do negocjowania protokołu HTTP/2.HttpProtocols.Http1AndHttp2 can't be used because TLS is required to negotiate HTTP/2. Bez protokołu TLS wszystkie połączenia z punktem końcowym domyślne do protokołu HTTP/1.1 i wywołania gRPC kończą się niepowodzeniem.Without TLS, all connections to the endpoint default to HTTP/1.1, and gRPC calls fail.

Klienta gRPC należy również skonfigurować tak, aby nie korzystał z protokołu TLS.The gRPC client must also be configured to not use TLS. Aby uzyskać więcej informacji, zobacz wywoływanie niezabezpieczonych usług gRPC przy użyciu programu .NET Core Client.For more information, see Call insecure gRPC services with .NET Core client.

Ostrzeżenie

Protokołu HTTP/2 bez protokołu TLS należy używać tylko podczas opracowywania aplikacji.HTTP/2 without TLS should only be used during app development. Aplikacje produkcyjne powinny zawsze korzystać z zabezpieczeń transportu.Production apps should always use transport security. Aby uzyskać więcej informacji, zobacz zagadnienia dotyczące zabezpieczeń w programie gRPC ASP.NET Core.For more information, see Security considerations in gRPC for ASP.NET Core.

elementy gRPC języka C# nie są generowane w kodzie z plików. protogRPC C# assets are not code generated from .proto files

gRPC generowanie kodu dla konkretnych klientów i klas podstawowych usług wymaga przywoływania plików protobuf i narzędzi z projektu.gRPC code generation of concrete clients and service base classes requires protobuf files and tooling to be referenced from a project. Należy uwzględnić:You must include:

  • pliki . proto , które mają być używane w <Protobuf> grupie elementów..proto files you want to use in the <Protobuf> item group. Zaimportowane pliki proto muszą odwoływać się do projektu.Imported .proto files must be referenced by the project.
  • Odwołanie do pakietu dla pakietu narzędzi gRPC gRPC. Tools.Package reference to the gRPC tooling package Grpc.Tools.

Aby uzyskać więcej informacji na temat generowania zasobów gRPC C#, zobacz Usługi gRPC w środowisku C# .For more information on generating gRPC C# assets, see Usługi gRPC w środowisku C#.

ASP.NET Core usługi gRPC Web App hosting Services wymagają tylko wygenerowania klasy bazowej usługi: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>

Aplikacja kliencka gRPC wykonująca wywołania gRPC potrzebuje tylko konkretnego wygenerowanego klienta:A gRPC client app making gRPC calls only needs the concrete client generated:

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

Projekty WPF nie mogą generować zasobów gRPC C# z plików. protoWPF projects unable to generate gRPC C# assets from .proto files

Projekty WPF mają znany problem , który uniemożliwia poprawne działanie generowania kodu gRPC.WPF projects have a known issue that prevents gRPC code generation from working correctly. Wszystkie typy gRPC wygenerowane w projekcie WPF przez odwołujące się do nich Grpc.Tools pliki i . proto spowodują błędy kompilacji, gdy są używane:Any gRPC types generated in a WPF project by referencing Grpc.Tools and .proto files will create compilation errors when used:

błąd CS0246: nie można znaleźć nazwy typu lub przestrzeni nazw "MyGrpcServices" (czy nie brakuje dyrektywy using lub odwołania do zestawu?)error CS0246: The type or namespace name 'MyGrpcServices' could not be found (are you missing a using directive or an assembly reference?)

Ten problem można obejść, wykonując następujące:You can workaround this issue by:

  1. Utwórz nowy projekt biblioteki klas .NET Core.Create a new .NET Core class library project.
  2. W nowym projekcie Dodaj odwołania, aby włączyć generowanie kodu w języku C# z plików * . proto:In the new project, add references to enable C# code generation from *.proto files:
    • Dodaj odwołanie do pakietu do pakietu GRPC. Tools .Add a package reference to Grpc.Tools package.
    • Dodaj pliki * . proto do <Protobuf> grupy elementów.Add *.proto files to the <Protobuf> item group.
  3. W aplikacji WPF Dodaj odwołanie do nowego projektu.In the WPF application, add a reference to the new project.

Aplikacja WPF może używać typów wygenerowanych przez gRPC z nowego projektu biblioteki klas.The WPF application can use the gRPC generated types from the new class library project.

Ostrzeżenie

ASP.NET Core gRPC nie jest obecnie obsługiwana w Azure App Service lub IIS.ASP.NET Core gRPC is not currently supported on Azure App Service or IIS. Implementacja protokołu HTTP/2 Http.Sys nie obsługuje nagłówków końcowych odpowiedzi HTTP, na których opiera się gRPC.The HTTP/2 implementation of Http.Sys does not support HTTP response trailing headers which gRPC relies on. Aby uzyskać więcej informacji, zobacz ten problemw serwisie GitHub.For more information, see this GitHub issue.