.NET Core での gRPC のトラブルシューティングTroubleshoot gRPC on .NET Core

James のニュートン-キングBy James Newton-King

このドキュメントでは、.NET で gRPC アプリを開発するときによく発生する問題について説明します。This document discusses commonly encountered problems when developing gRPC apps on .NET.

クライアントとサービスの SSL/TLS の構成が一致しませんMismatch between client and service SSL/TLS configuration

GRPC テンプレートとサンプルでは、トランスポート層セキュリティ (TLS)を使用して、既定で grpc サービスをセキュリティで保護しています。The gRPC template and samples use Transport Layer Security (TLS) to secure gRPC services by default. gRPC クライアントはセキュリティで保護された接続を使用して、セキュリティで保護された gRPC サービスを正常に呼び出す必要があります。gRPC clients need to use a secure connection to call secured gRPC services successfully.

アプリの起動時に書き込まれたログで、ASP.NET Core gRPC サービスが TLS を使用していることを確認できます。You can verify the ASP.NET Core gRPC service is using TLS in the logs written on app start. サービスは、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

.NET Core クライアントは、サーバーアドレスの https を使用して、セキュリティで保護された接続で呼び出しを行う必要があります。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);
}

すべての gRPC クライアント実装は TLS をサポートしています。All gRPC client implementations support TLS. 他の言語の gRPC クライアントでは、通常、SslCredentialsで構成されたチャネルが必要です。gRPC clients from other languages typically require the channel configured with SslCredentials. SslCredentials は、クライアントが使用する証明書を指定し、セキュリティで保護されていない資格情報の代わりに使用する必要があります。SslCredentials specifies the certificate that the client will use, and it must be used instead of insecure credentials. 異なる gRPC クライアント実装で TLS を使用するように構成する例については、「 Grpc 認証」を参照してください。For examples of configuring the different gRPC client implementations to use TLS, see gRPC Authentication.

信頼されていない/無効な証明書を使用して gRPC サービスを呼び出すCall a gRPC service with an untrusted/invalid certificate

.NET gRPC クライアントでは、サービスに信頼された証明書が必要です。The .NET gRPC client requires the service to have a trusted certificate. 信頼された証明書を使用せずに gRPC サービスを呼び出すと、次のエラーメッセージが返されます。The following error message is returned when calling a gRPC service without a trusted certificate:

ハンドルされていない例外です。Unhandled exception. System.net.http.httprequestexception: SSL 接続を確立できませんでした。内部例外を参照してください。System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> を実行しています。 AuthenticationException: 検証プロシージャによると、リモート証明書が無効です。---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

このエラーは、アプリをローカルでテストしていて、ASP.NET Core HTTPS 開発証明書が信頼されていない場合に表示されることがあります。You may see this error if you are testing your app locally and the ASP.NET Core HTTPS development certificate is not trusted. この問題を解決する手順については、「Windows と macOS で ASP.NET Core HTTPS 開発証明書を信頼します」を参照してください。For instructions to fix this issue, see Trust the ASP.NET Core HTTPS development certificate on Windows and macOS.

別のコンピューターで gRPC サービスを呼び出していて、その証明書を信頼できない場合、gRPC クライアントは無効な証明書を無視するように構成できます。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. 次のコードでは、 Httpclienthandler. ServerCertificateCustomValidationCallbackを使用して、信頼された証明書がない呼び出しを許可します。The following code uses HttpClientHandler.ServerCertificateCustomValidationCallback to allow calls without a trusted certificate:

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

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

警告

信頼されていない証明書は、アプリの開発中にのみ使用してください。Untrusted certificates should only be used during app development. 実稼働アプリケーションでは、常に有効な証明書を使用する必要があります。Production apps should always use valid certificates.

.NET Core クライアントを使用してセキュリティで保護される gRPC サービスを呼び出すCall insecure gRPC services with .NET Core client

.NET Core クライアントでセキュリティで保護されていない gRPC サービスを呼び出すには、追加の構成が必要です。Additional configuration is required to call insecure gRPC services with the .NET Core client. GRPC クライアントは、System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport スイッチを true に設定し、サーバーアドレスに http を使用する必要があります。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);

MacOS で gRPC アプリを開始できません ASP.NET CoreUnable to start ASP.NET Core gRPC app on macOS

Kestrel では、macOS での TLS と Windows 7 などの古いバージョンの HTTP/2 はサポートされていません。Kestrel doesn't support HTTP/2 with TLS on macOS and older Windows versions such as Windows 7. ASP.NET Core gRPC テンプレートとサンプルでは、既定で TLS が使用されます。The ASP.NET Core gRPC template and samples use TLS by default. GRPC サーバーを起動しようとすると、次のエラーメッセージが表示されます。You'll see the following error message when you attempt to start the gRPC server:

IPv4 ループバックインターフェイスの https://localhost:5001 にバインドできませんでした。 ALPN サポートがないため、macOS で ' HTTP/2 over TLS はサポートされていません。 '。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.'.

この問題を回避するには、TLS を使用せずに HTTP/2 を使用するように Kestrel と grpc クライアントを構成します。To work around this issue, configure Kestrel and the gRPC client to use HTTP/2 without TLS. これは開発時にのみ実行してください。You should only do this during development. TLS を使用しないと、gRPC メッセージが暗号化なしで送信されます。Not using TLS will result in gRPC messages being sent without encryption.

Kestrel では、 Program.csで TLS を使用せずに HTTP/2 エンドポイントを構成する必要があります。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>();
        });

HTTP/2 エンドポイントが TLS を使用せずに構成されている場合、エンドポイントのListenoptionsHttpProtocols.Http2に設定されている必要があります。When an HTTP/2 endpoint is configured without TLS, the endpoint's ListenOptions.Protocols must be set to HttpProtocols.Http2. HTTP/2 のネゴシエートに TLS が必要であるため、HttpProtocols.Http1AndHttp2 を使用することはできません。HttpProtocols.Http1AndHttp2 can't be used because TLS is required to negotiate HTTP/2. TLS を使用しない場合、エンドポイントへのすべての接続は既定の HTTP/1.1 に設定され、gRPC の呼び出しは失敗します。Without TLS, all connections to the endpoint default to HTTP/1.1, and gRPC calls fail.

GRPC クライアントは、TLS を使用しないように構成する必要もあります。The gRPC client must also be configured to not use TLS. 詳細については、「 .Net Core クライアントを使用した安全でない gRPC サービスの呼び出し」を参照してください。For more information, see Call insecure gRPC services with .NET Core client.

警告

TLS を使用しない HTTP/2 は、アプリの開発中にのみ使用してください。HTTP/2 without TLS should only be used during app development. 運用アプリでは、常にトランスポートセキュリティを使用する必要があります。Production apps should always use transport security. 詳細については、「 gRPC のセキュリティに関する考慮事項 ASP.NET Core」を参照してください。For more information, see Security considerations in gRPC for ASP.NET Core.

gRPC C#資産は、proto ファイルから生成されたコードではありませんgRPC C# assets are not code generated from .proto files

具象クライアントとサービス基底クラスの gRPC コード生成には、protobuf ファイルとツールをプロジェクトから参照する必要があります。gRPC code generation of concrete clients and service base classes requires protobuf files and tooling to be referenced from a project. 次のものを含める必要があります。You must include:

  • <Protobuf> 項目グループで使用するプロトコルファイル。.proto files you want to use in the <Protobuf> item group. インポートされたプロトコルファイルは、プロジェクトによって参照される必要があります。Imported .proto files must be referenced by the project.
  • GRPC ツールパッケージGrpc.Toolsに対するパッケージリファレンス。Package reference to the gRPC tooling package Grpc.Tools.

GRPC C#アセットの生成の詳細については、「C# を使用した gRPC サービス」を参照してください。For more information on generating gRPC C# assets, see C# を使用した gRPC サービス.

既定では、<Protobuf> 参照によって、具象クライアントとサービス基本クラスが生成されます。By default, a <Protobuf> reference generates a concrete client and a service base class. 参照要素の GrpcServices 属性は、資産の生成をC#制限するために使用できます。The reference element's GrpcServices attribute can be used to limit C# asset generation. 有効な GrpcServices オプションは次のとおりです。Valid GrpcServices options are:

  • Both (存在しない場合は既定)Both (default when not present)
  • Server
  • Client
  • None

GRPC サービスをホストしている ASP.NET Core web アプリには、生成されたサービス基本クラスのみが必要です。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>

GRPC 呼び出しを行う gRPC クライアントアプリでは、具象クライアントのみが生成されます。A gRPC client app making gRPC calls only needs the concrete client generated:

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

WPF プロジェクトは、proto ファイルからC# grpc アセットを生成できませんWPF projects unable to generate gRPC C# assets from .proto files

WPF プロジェクトには、gRPC コード生成が正常に動作しないという既知の問題があります。WPF projects have a known issue that prevents gRPC code generation from working correctly. Grpc.Tools ファイルとプロトコルファイルを参照することによって WPF プロジェクトで生成された grpc の種類では、次のようなコンパイルエラーが発生します。Any gRPC types generated in a WPF project by referencing Grpc.Tools and .proto files will create compilation errors when used:

エラー CS0246: 型または名前空間の名前 ' MyGrpcServices ' が見つかりませんでした。 using ディレクティブまたはアセンブリ参照が指定されていることを確認してください。error CS0246: The type or namespace name 'MyGrpcServices' could not be found (are you missing a using directive or an assembly reference?)

この問題を回避するには、次の方法があります。You can workaround this issue by:

  1. 新しい .NET Core クラスライブラリプロジェクトを作成します。Create a new .NET Core class library project.
  2. 新しいプロジェクトで、 C# * のファイルからコード生成を有効にするための参照を追加します。In the new project, add references to enable C# code generation from *.proto files:
    • Grpc.Tools パッケージにパッケージ参照を追加します。Add a package reference to Grpc.Tools package.
    • 項目グループに * .proto<Protobuf> ファイルを追加します。Add *.proto files to the <Protobuf> item group.
  3. WPF アプリケーションで、新しいプロジェクトへの参照を追加します。In the WPF application, add a reference to the new project.

WPF アプリケーションでは、新しいクラスライブラリプロジェクトから、gRPC によって生成された型を使用できます。The WPF application can use the gRPC generated types from the new class library project.

gRPC は Azure App Service ではサポートされていませんgRPC not supported on Azure App Service

警告

現在、ASP.NET Core gRPC は Azure App Service または IIS 上でサポートされていません。ASP.NET Core gRPC is not currently supported on Azure App Service or IIS. Http.Sys の HTTP/2 実装では、gRPC が依存する HTTP 応答の末尾のヘッダーがサポートされていません。The HTTP/2 implementation of Http.Sys does not support HTTP response trailing headers which gRPC relies on. 詳細については、次を参照してください。この GitHub の問題します。For more information, see this GitHub issue.