Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Írta: James Newton-King
Note
Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.
Warning
A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .
Ez a dokumentum a gRPC-alkalmazások .NET-en való fejlesztése során gyakran előforduló problémákat ismerteti.
Eltérés az ügyfél és a szolgáltatás SSL-/TLS-konfigurációja között
A gRPC-sablon és -minták a Transport Layer Security (TLS) használatával biztosítják alapértelmezés szerint a gRPC-szolgáltatásokat. A gRPC-ügyfeleknek biztonságos kapcsolatot kell használniuk a biztonságos gRPC-szolgáltatások sikeres meghívásához.
Ellenőrizheti, hogy a ASP.NET Core gRPC szolgáltatás TLS-t használ-e az alkalmazás indításakor írt naplókban. A szolgáltatás egy HTTPS-végpontot figyel:
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
A .NET-ügyfélnek a kiszolgáló címében kell használnia https a hívások biztonságos kapcsolattal való indításához:
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
Minden gRPC-ügyfél-implementáció támogatja a TLS-t. A más nyelvekről származó gRPC-ügyfelek általában megkövetelik a csatorna konfigurálását SslCredentials.
SslCredentials Meghatározza az ügyfél által használandó tanúsítványt, és azt a nem biztonságos hitelesítő adatok helyett kell használni. Példák a különböző gRPC-ügyfél-implementációk TLS használatára való konfigurálására: gRPC-hitelesítés.
gRPC szolgáltatás meghívása nem megbízható/érvénytelen tanúsítvánnyal
A .NET gRPC-ügyfél megköveteli, hogy a szolgáltatás megbízható tanúsítvánnyal rendelkezzen. A rendszer a következő hibaüzenetet adja vissza, ha megbízható tanúsítvány nélkül hív meg egy gRPC-szolgáltatást:
Kezeletlen kivétel. System.Net.Http.HttpRequestException: Az SSL-kapcsolat nem hozható létre, lásd a belső kivételt. >--- System.Security.Authentication.AuthenticationException: A távoli tanúsítvány érvénytelen az érvényesítési eljárásnak megfelelően.
Ez a hiba akkor jelenhet meg, ha helyileg teszteli az alkalmazást, és a ASP.NET Core HTTPS fejlesztési tanúsítvány nem megbízható. A probléma megoldására vonatkozó utasításokért tekintse meg a ASP.NET Core HTTPS fejlesztői tanúsítvány megbízhatóságát Windows és macOS rendszeren.
Ha egy gRPC-szolgáltatást hív meg egy másik gépen, és nem tud megbízni a tanúsítványban, akkor a gRPC-ügyfél konfigurálható úgy, hogy figyelmen kívül hagyja az érvénytelen tanúsítványt. A következő kód a megbízható tanúsítvány nélküli hívások engedélyezésére szolgál HttpClientHandler.ServerCertificateCustomValidationCallback :
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);
A gRPC-ügyfél-előállító megbízható tanúsítvány nélkül engedélyezi a hívásokat. ConfigurePrimaryHttpMessageHandler A bővítménymetódus használatával konfigurálja a kezelőt az ügyfélen:
var services = new ServiceCollection();
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
return handler;
});
Warning
A nem megbízható tanúsítványokat csak az alkalmazásfejlesztés során szabad használni. A gyártásban lévő alkalmazásoknak mindig érvényes tanúsítványokat kell használniuk.
Nem biztonságos gRPC-szolgáltatások hívása .NET-ügyféllel
A .NET gRPC-ügyfél biztonság nélküli gRPC-szolgáltatásokat hívhat meg a kiszolgáló címének http megadásával. Például: GrpcChannel.ForAddress("http://localhost:5000").
Az alkalmazás által használt .NET-verziótól függően további követelmények vonatkoznak a nem biztonságos gRPC-szolgáltatások meghívására:
- A .NET 5 vagy újabb verziójához a Grpc.Net.Client 2.32.0-s vagy újabb verziója szükséges.
- A .NET Core 3.x további konfigurációt igényel. Az alkalmazásnak be kell állítania a
System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupportkapcsolóttrue. További információ: Asp.Net Core 3.x: Nem biztonságos gRPC-szolgáltatások meghívása a .NET-ügyféllel:
Important
A nem biztonságos gRPC-szolgáltatásokat http/2-csak porton kell üzemeltetni. További információ: ASP.NET Core protokoll egyeztetése.
Nem indítható el ASP.NET Core gRPC-alkalmazás macOS rendszeren
Kestrel nem támogatja a HTTP/2-t a tLS-sel macOS rendszeren a .NET 8 előtt. A ASP.NET Core gRPC-sablon és -minták alapértelmezés szerint TLS-t használnak. A gRPC-kiszolgáló indításakor a következő hibaüzenet jelenik meg:
Nem lehet csatlakozni https://localhost:5001 az IPv4-visszacsatolási felületen: "A HTTP/2 TLS-en keresztül nem támogatott macOS rendszeren, mert hiányzik az ALPN-támogatás."
A probléma megoldásához a .NET 7 vagy korábbi verzióiban konfigurálja a Kestrel és a gRPC-ügyfelet a HTTP/2 TLS nélküli használatára. Ezt csak a fejlesztés során szabad elvégeznie. A TLS használatának mellőzése esetén a gRPC-üzenetek titkosítás nélkül lesznek elküldve. További információ: ASP.NET Core a .NET 7-ben: Nem indítható el ASP.NET Core gRPC-alkalmazás macOS rendszeren.
A gRPC C#-objektumok nem fájlokból .proto generált kód
A konkrét ügyfelek és a szolgáltatásbázis-osztályok gRPC-kódgenerálásához protobuf fájlokat és eszközöket kell hivatkozni egy projektből. A következőket kell tartalmaznia:
-
.protoaz elemcsoportban<Protobuf>használni kívánt fájlok. Az importált.protofájlokra a projektnek hivatkoznia kell. - Csomaghivatkozás a Grpc.Tools gRPC eszközcsomagra.
A gRPC C#-eszközök létrehozásával kapcsolatos további információkért lásd a GRPC-szolgáltatásokat a C#-tal.
A gRPC-szolgáltatásokat üzemeltető ASP.NET Core-webalkalmazásnak csak a létrehozott alapszolgáltatás-osztályra van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
A gRPC-hívásokat kezdeményező gRPC-ügyfélalkalmazásnak csak a létrehozott konkrét ügyfélre van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
A WPF-projektek nem tudnak gRPC C#-objektumokat létrehozni fájlokból .proto
A WPF-projektek ismert problémával rendelkeznek, amely megakadályozza a gRPC-kódlétrehozást a megfelelő működésben. A WPF projektben a Grpc.Tools és .proto fájlokra való hivatkozással generált gRPC-típusok fordítási hibákat okoznak a használat során.
CS0246-os hiba: A "MyGrpcServices" típus- vagy névtérnév nem található (hiányzik egy felhasználói irányelv vagy egy szerelvényhivatkozás?)
A problémát a következő módon lehet megkerülni:
- Hozzon létre egy új .NET-osztálytárprojektet.
- Az új projektben adjon hozzá hivatkozásokat a C#-kód fájlokból való
.protolétrehozásának engedélyezéséhez:- Adja hozzá a következő csomaghivatkozásokat:
- Adj hozzá
.protofájlokat az<Protobuf>elemcsoporthoz.
- A WPF-alkalmazásban adjon hozzá egy hivatkozást az új projekthez.
A WPF-alkalmazás használhatja az új osztálytárprojektből létrehozott gRPC-típusokat.
Alkönyvtárban üzemeltetett gRPC-szolgáltatások meghívása
Warning
Számos külső gRPC-eszköz nem támogatja az alkönyvtárakban üzemeltetett szolgáltatásokat. Fontolja meg a gRPC gyökérkönyvtárként való üzemeltetésének módját.
A gRPC-csatorna címének elérési útösszetevőjét a rendszer figyelmen kívül hagyja a gRPC-hívások során. Nem használható GrpcChannel.ForAddress("https://localhost:5001/ignored_path") például a ignored_path szolgáltatáshoz tartozó gRPC-hívások útválasztása során.
A cím elérési útja figyelmen kívül lesz hagyva, mert a gRPC szabványosított, előíró címstruktúrával rendelkezik. A gRPC-címek egyesítik a csomag, a szolgáltatás és a metódus nevét: https://localhost:5001/PackageName.ServiceName/MethodName.
Vannak olyan esetek, amikor egy alkalmazásnak gRPC-hívásokkal kell tartalmaznia egy elérési utat. Ha például egy ASP.NET Core gRPC-alkalmazást üzemeltetnek egy IIS-címtárban, és a címtárat bele kell foglalni a kérésbe. Ha egy elérési út szükséges, az alábbi egyéni SubdirectoryHandler beállítással adható hozzá a gRPC-híváshoz:
public class SubdirectoryHandler : DelegatingHandler
{
private readonly string _subdirectory;
public SubdirectoryHandler(HttpMessageHandler innerHandler, string subdirectory)
: base(innerHandler)
{
_subdirectory = subdirectory;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var old = request.RequestUri;
var url = $"{old.Scheme}://{old.Host}:{old.Port}";
url += $"{_subdirectory}{request.RequestUri.AbsolutePath}";
request.RequestUri = new Uri(url, UriKind.Absolute);
return base.SendAsync(request, cancellationToken);
}
}
SubdirectoryHandler a gRPC-csatorna létrehozásakor használatos.
var handler = new SubdirectoryHandler(new HttpClientHandler(), "/MyApp");
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Az előző kód:
- Létrehoz egy
SubdirectoryHandlera/MyAppelérési úttal. - Konfigurál egy csatornát a
SubdirectoryHandlerhasználatára. - Meghívja a gRPC szolgáltatást a következővel
SayHelloAsync: . A gRPC-hívást a rendszer elküldi a következőnekhttps://localhost:5001/MyApp/greet.Greeter/SayHello: .
Másik lehetőségként egy ügyfél gyártói is konfigurálható SubdirectoryHandlerAddHttpMessageHandler használatával.
A gRPC-ügyfél konfigurálása HTTP/3 használatára
A .NET gRPC-ügyfél támogatja a HTTP/3-at a .NET 6-os vagy újabb verziójával. Ha a kiszolgáló egy válaszfejlécet alt-svc küld az ügyfélnek, amely azt jelzi, hogy a kiszolgáló támogatja a HTTP/3-at, az ügyfél automatikusan http/3-ra frissíti a kapcsolatot. További információ: HTTP/3 használata a ASP.NET Core Kestrel webkiszolgálóval.
Az A DelegatingHandler használatával kényszerítheti a gRPC-ügyfelet a HTTP/3 használatára. A HTTP/3 kényszerítése elkerüli a kérés frissítésének többletterhelését. A HTTP/3 kényszerítése a következőhöz hasonló kóddal:
public class Http3Handler : DelegatingHandler
{
public Http3Handler() { }
public Http3Handler(HttpMessageHandler innerHandler) : base(innerHandler) { }
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Version = HttpVersion.Version30;
request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
return base.SendAsync(request, cancellationToken);
}
}
Http3Handler a gRPC-csatorna létrehozásakor használatos. Az alábbi kód egy olyan csatornát hoz létre, amely Http3Handler használatára van konfigurálva.
var handler = new Http3Handler(new HttpClientHandler());
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "GreeterClient" });
Másik lehetőségként egy ügyfél gyártói is konfigurálható Http3HandlerAddHttpMessageHandler használatával.
GRPC létrehozása Alpine Linuxon
A Grpc.Tools csomag .NET-típusokat hoz létre a .proto fájlokból egy kötegelt natív bináris, nevű protoc. További lépések szükségesek a gRPC-alkalmazások olyan platformokon való létrehozásához, amelyeket a natív bináris fájlok nem támogatnak, például az Alpine Linuxban Grpc.Tools.
Kód létrehozása előre
Az egyik megoldás a kód idő előtti létrehozása.
- Helyezze át a
.protofájlokat és aGrpc.Toolscsomaghivatkozást egy új projektbe. - Tegye közzé a projektet NuGet-csomagként, és töltse fel egy NuGet-hírcsatornába.
- Frissítse az alkalmazást a NuGet-csomagra való hivatkozáshoz.
Az előző lépésekkel az alkalmazásnak már nem kell buildelést végrehajtania Grpc.Tools , mert a kód előre létrejön.
Natív bináris fájlok testreszabása Grpc.Tools
Grpc.Tools támogatja az egyéni natív bináris fájlok használatát. Ez a funkció lehetővé teszi, hogy a gRPC-eszközök olyan környezetekben fussanak, amelyben a natív bináris fájlok kötegei nem támogatottak.
Készítse el vagy szerezze be a protoc és grpc_csharp_plugin natív binárisokat, és konfigurálja a Grpc.Tools azok használatára. Konfigurálja a natív bináris fájlokat a következő környezeti változók beállításával:
-
PROTOBUF_PROTOC- A protokollpufferek fordítójának teljes elérési útja -
GRPC_PROTOC_PLUGIN- A grpc_csharp_plugin teljes elérési útja
Az Alpine Linux esetében a közösség biztosít csomagokat a protokollpufferek fordítójához és a gRPC beépülő modulokhoz a következő helyen: https://pkgs.alpinelinux.org/.
# Build or install the binaries for your architecture.
# For Alpine Linux, the grpc-plugins package can be used.
# See https://pkgs.alpinelinux.org/package/edge/community/x86_64/grpc-plugins
apk add grpc-plugins # Alpine Linux specific package installer
# Set environment variables for the built/installed protoc
# and grpc_csharp_plugin binaries
export PROTOBUF_PROTOC=/usr/bin/protoc
export GRPC_PROTOC_PLUGIN=/usr/bin/grpc_csharp_plugin
# When dotnet build runs, the Grpc.Tools NuGet package
# uses the binaries pointed to by the environment variables.
dotnet build
A nem támogatott architektúrák használatával Grpc.Tools kapcsolatos további információkért tekintse meg a gRPC buildintegrációs dokumentációját.
gRPC-hívás időtúllépése innen: HttpClient.Timeout
HttpClient alapértelmezés szerint 100 másodperces időtúllépéssel van konfigurálva. Ha a GrpcChannel úgy van konfigurálva, hogy egy HttpClient-et használjon, a hosszú ideig futó gRPC-streamhívásokat megszakítják, ha nem fejeződnek be az időkorláton belül.
System.OperationCanceledException: The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
Ezt a hibát többféleképpen is kijavíthatja. Az első lépés HttpClient.Timeout nagyobb értékre való konfigurálása. Timeout.InfiniteTimeSpan kikapcsolja az időkorlátot.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(handler) { Timeout = Timeout.InfiniteTimeSpan };
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greeter.GreeterClient(channel);
Másik lehetőségként kerülje HttpClient létrehozását és helyette állítsa be GrpcChannel.HttpHandler-et.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);
Ez a dokumentum a gRPC-alkalmazások .NET-en való fejlesztése során gyakran előforduló problémákat ismerteti.
Eltérés az ügyfél és a szolgáltatás SSL-/TLS-konfigurációja között
A gRPC-sablon és -minták a Transport Layer Security (TLS) használatával biztosítják alapértelmezés szerint a gRPC-szolgáltatásokat. A gRPC-ügyfeleknek biztonságos kapcsolatot kell használniuk a biztonságos gRPC-szolgáltatások sikeres meghívásához.
Ellenőrizheti, hogy a ASP.NET Core gRPC szolgáltatás TLS-t használ-e az alkalmazás indításakor írt naplókban. A szolgáltatás egy HTTPS-végpontot figyel:
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
A .NET-ügyfélnek a kiszolgáló címében kell használnia https a hívások biztonságos kapcsolattal való indításához:
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);
}
Minden gRPC-ügyfél-implementáció támogatja a TLS-t. A más nyelvekről származó gRPC-ügyfelek általában megkövetelik a csatorna konfigurálását SslCredentials.
SslCredentials Meghatározza az ügyfél által használandó tanúsítványt, és azt a nem biztonságos hitelesítő adatok helyett kell használni. Példák a különböző gRPC-ügyfél-implementációk TLS használatára való konfigurálására: gRPC-hitelesítés.
gRPC szolgáltatás meghívása nem megbízható/érvénytelen tanúsítvánnyal
A .NET gRPC-ügyfél megköveteli, hogy a szolgáltatás megbízható tanúsítvánnyal rendelkezzen. A rendszer a következő hibaüzenetet adja vissza, ha megbízható tanúsítvány nélkül hív meg egy gRPC-szolgáltatást:
Kezeletlen kivétel. System.Net.Http.HttpRequestException: Az SSL-kapcsolat nem hozható létre, lásd a belső kivételt. >--- System.Security.Authentication.AuthenticationException: A távoli tanúsítvány érvénytelen az érvényesítési eljárásnak megfelelően.
Ez a hiba akkor jelenhet meg, ha helyileg teszteli az alkalmazást, és a ASP.NET Core HTTPS fejlesztési tanúsítvány nem megbízható. A probléma megoldására vonatkozó utasításokért tekintse meg a ASP.NET Core HTTPS fejlesztői tanúsítvány megbízhatóságát Windows és macOS rendszeren.
Ha egy gRPC-szolgáltatást hív meg egy másik gépen, és nem tud megbízni a tanúsítványban, akkor a gRPC-ügyfél konfigurálható úgy, hogy figyelmen kívül hagyja az érvénytelen tanúsítványt. A következő kód a megbízható tanúsítvány nélküli hívások engedélyezésére szolgál HttpClientHandler.ServerCertificateCustomValidationCallback :
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
A gRPC-ügyfél-előállító megbízható tanúsítvány nélkül engedélyezi a hívásokat. ConfigurePrimaryHttpMessageHandler A bővítménymetódus használatával konfigurálja a kezelőt az ügyfélen:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
return handler;
});
Warning
A nem megbízható tanúsítványokat csak az alkalmazásfejlesztés során szabad használni. A gyártásban lévő alkalmazásoknak mindig érvényes tanúsítványokat kell használniuk.
Nem biztonságos gRPC-szolgáltatások hívása .NET-ügyféllel
A .NET gRPC-ügyfél biztonság nélküli gRPC-szolgáltatásokat hívhat meg a kiszolgáló címének http megadásával. Például: GrpcChannel.ForAddress("http://localhost:5000").
Az alkalmazás által használt .NET-verziótól függően további követelmények vonatkoznak a nem biztonságos gRPC-szolgáltatások meghívására:
A .NET 5 vagy újabb verziójához a Grpc.Net.Client 2.32.0-s vagy újabb verziója szükséges.
A .NET Core 3.x további konfigurációt igényel. Az alkalmazásnak a következőre kell beállítania a
System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupportkapcsolóttrue:// 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);
A System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport kapcsoló csak a .NET Core 3.x-hez szükséges. Nem tesz semmit a .NET 5-ben, és nem szükséges.
Important
A nem biztonságos gRPC-szolgáltatásokat http/2-csak porton kell üzemeltetni. További információ: ASP.NET Core protokoll egyeztetése.
Nem indítható el ASP.NET Core gRPC-alkalmazás macOS rendszeren
Kestrel nem támogatja a HTTP/2-t a tLS-sel macOS rendszeren a .NET 8 előtt. A ASP.NET Core gRPC-sablon és -minták alapértelmezés szerint TLS-t használnak. A gRPC-kiszolgáló indításakor a következő hibaüzenet jelenik meg:
Nem lehet csatlakozni https://localhost:5001 az IPv4-visszacsatolási felületen: "A HTTP/2 TLS-en keresztül nem támogatott macOS rendszeren, mert hiányzik az ALPN-támogatás."
A probléma megoldásához a .NET 7 vagy korábbi verzióiban konfigurálja a Kestrel és a gRPC-ügyfelet a HTTP/2 TLS nélküli használatára. Ezt csak a fejlesztés során szabad elvégeznie. A TLS használatának mellőzése esetén a gRPC-üzenetek titkosítás nélkül lesznek elküldve.
Kestrel HTTP/2-végpontot kell konfigurálnia TLS nélkül a következőben Program.cs:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(options =>
{
// Setup a HTTP/2 endpoint without TLS.
options.ListenLocalhost(<5287>, o => o.Protocols =
HttpProtocols.Http2);
});
- Az előző kódban cserélje le a localhost portszámot
5287aHTTPgRPC szolgáltatásprojektbenHTTPSmegadott (nemProperties/launchSettings.json) portszámra.
Ha egy HTTP/2-végpont TLS nélkül van konfigurálva, a végpont ListenOptions.Protokolljait a következőre HttpProtocols.Http2kell állítani: .
HttpProtocols.Http1AndHttp2 nem használható, mert a HTTP/2 egyeztetéséhez TLS szükséges. TLS nélkül a végponthoz való összes kapcsolat alapértelmezés szerint HTTP/1.1, és a gRPC-hívások sikertelenek.
A gRPC-ügyfelet úgy is konfigurálnia kell, hogy ne használja a TLS-t. További információ: Nem biztonságos gRPC-szolgáltatások meghívása .NET-ügyféllel.
Warning
A HTTP/2 TLS nélkül csak az alkalmazásfejlesztés során használható. Az éles alkalmazásoknak mindig az átviteli biztonságot kell használniuk. További információkért tekintse meg a ASP.NET Core-ra vonatkozó gRPC biztonsági szempontjait.
A gRPC C#-objektumok nem fájlokból .proto generált kód
A konkrét ügyfelek és a szolgáltatásbázis-osztályok gRPC-kódgenerálásához protobuf fájlokat és eszközöket kell hivatkozni egy projektből. A következőket kell tartalmaznia:
-
.protoaz elemcsoportban<Protobuf>használni kívánt fájlok. Az importált.protofájlokra a projektnek hivatkoznia kell. - Csomaghivatkozás a Grpc.Tools gRPC eszközcsomagra.
A gRPC C#-eszközök létrehozásával kapcsolatos további információkért lásd a GRPC-szolgáltatásokat a C#-tal.
A gRPC-szolgáltatásokat üzemeltető ASP.NET Core-webalkalmazásnak csak a létrehozott alapszolgáltatás-osztályra van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
A gRPC-hívásokat kezdeményező gRPC-ügyfélalkalmazásnak csak a létrehozott konkrét ügyfélre van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
A WPF-projektek nem tudnak gRPC C#-objektumokat létrehozni fájlokból .proto
A WPF-projektek ismert problémával rendelkeznek, amely megakadályozza a gRPC-kódlétrehozást a megfelelő működésben. A WPF projektben a Grpc.Tools és .proto fájlokra való hivatkozással generált gRPC-típusok fordítási hibákat okoznak a használat során.
CS0246-os hiba: A "MyGrpcServices" típus- vagy névtérnév nem található (hiányzik egy felhasználói irányelv vagy egy szerelvényhivatkozás?)
A problémát a következő módon lehet megkerülni:
- Hozzon létre egy új .NET-osztálytárprojektet.
- Az új projektben adjon hozzá hivatkozásokat a C#-kód fájlokból való
.protolétrehozásának engedélyezéséhez:- Adja hozzá a következő csomaghivatkozásokat:
- Adj hozzá
.protofájlokat az<Protobuf>elemcsoporthoz.
- A WPF-alkalmazásban adjon hozzá egy hivatkozást az új projekthez.
A WPF-alkalmazás használhatja az új osztálytárprojektből létrehozott gRPC-típusokat.
Alkönyvtárban üzemeltetett gRPC-szolgáltatások meghívása
Warning
Számos külső gRPC-eszköz nem támogatja az alkönyvtárakban üzemeltetett szolgáltatásokat. Fontolja meg a gRPC gyökérkönyvtárként való üzemeltetésének módját.
A gRPC-csatorna címének elérési útösszetevőjét a rendszer figyelmen kívül hagyja a gRPC-hívások során. Nem használható GrpcChannel.ForAddress("https://localhost:5001/ignored_path") például a ignored_path szolgáltatáshoz tartozó gRPC-hívások útválasztása során.
A cím elérési útja figyelmen kívül lesz hagyva, mert a gRPC szabványosított, előíró címstruktúrával rendelkezik. A gRPC-címek egyesítik a csomag, a szolgáltatás és a metódus nevét: https://localhost:5001/PackageName.ServiceName/MethodName.
Vannak olyan esetek, amikor egy alkalmazásnak gRPC-hívásokkal kell tartalmaznia egy elérési utat. Ha például egy ASP.NET Core gRPC-alkalmazást üzemeltetnek egy IIS-címtárban, és a címtárat bele kell foglalni a kérésbe. Ha egy elérési út szükséges, az alábbi egyéni SubdirectoryHandler beállítással adható hozzá a gRPC-híváshoz:
/// <summary>
/// A delegating handler that adds a subdirectory to the URI of gRPC requests.
/// </summary>
public class SubdirectoryHandler : DelegatingHandler
{
private readonly string _subdirectory;
public SubdirectoryHandler(HttpMessageHandler innerHandler, string subdirectory)
: base(innerHandler)
{
_subdirectory = subdirectory;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var old = request.RequestUri;
var url = $"{old.Scheme}://{old.Host}:{old.Port}";
url += $"{_subdirectory}{request.RequestUri.AbsolutePath}";
request.RequestUri = new Uri(url, UriKind.Absolute);
return base.SendAsync(request, cancellationToken);
}
}
SubdirectoryHandler a gRPC-csatorna létrehozásakor használatos.
var handler = new SubdirectoryHandler(new HttpClientHandler(), "/MyApp");
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
Az előző kód:
- Létrehoz egy
SubdirectoryHandlera/MyAppelérési úttal. - Konfigurál egy csatornát a
SubdirectoryHandlerhasználatára. - Meghívja a gRPC szolgáltatást a következővel
SayHelloAsync: . A gRPC-hívást a rendszer elküldi a következőnekhttps://localhost:5001/MyApp/greet.Greeter/SayHello: .
Másik lehetőségként egy ügyfél gyártói is konfigurálható SubdirectoryHandlerAddHttpMessageHandler használatával.
A gRPC-ügyfél konfigurálása HTTP/3 használatára
A .NET gRPC-ügyfél támogatja a HTTP/3-at a .NET 6-os vagy újabb verziójával. Ha a kiszolgáló egy válaszfejlécet alt-svc küld az ügyfélnek, amely azt jelzi, hogy a kiszolgáló támogatja a HTTP/3-at, az ügyfél automatikusan http/3-ra frissíti a kapcsolatot. A HTTP/3 kiszolgálón való engedélyezéséről további információt a HTTP/3 használata a ASP.NET Core Kestrel webkiszolgálóval című témakörben talál.
A .NET 8 HTTP/3 támogatása alapértelmezés szerint engedélyezve van. A .NET 6 és a .NET 7 HTTP/3 támogatását a projektfájlban található konfigurációs jelzővel kell engedélyezni:
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.SocketsHttpHandler.Http3Support" Value="true" />
</ItemGroup>
System.Net.SocketsHttpHandler.Http3Support
AppContext.SetSwitch használatával is beállítható.
Az A DelegatingHandler használatával kényszerítheti a gRPC-ügyfelet a HTTP/3 használatára. A HTTP/3 kényszerítése elkerüli a kérés frissítésének többletterhelését. A HTTP/3 kényszerítése a következőhöz hasonló kóddal:
/// <summary>
/// A delegating handler that changes the request HTTP version to HTTP/3.
/// </summary>
public class Http3Handler : DelegatingHandler
{
public Http3Handler() { }
public Http3Handler(HttpMessageHandler innerHandler) : base(innerHandler) { }
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Version = HttpVersion.Version30;
request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
return base.SendAsync(request, cancellationToken);
}
}
Http3Handler a gRPC-csatorna létrehozásakor használatos. Az alábbi kód egy olyan csatornát hoz létre, amely Http3Handler használatára van konfigurálva.
var handler = new Http3Handler(new HttpClientHandler());
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
Másik lehetőségként egy ügyfél gyártói is konfigurálható Http3HandlerAddHttpMessageHandler használatával.
GRPC létrehozása Alpine Linuxon
A Grpc.Tools csomag .NET-típusokat hoz létre a .proto fájlokból egy kötegelt natív bináris, nevű protoc. További lépések szükségesek a gRPC-alkalmazások olyan platformokon való létrehozásához, amelyeket a natív bináris fájlok nem támogatnak, például az Alpine Linuxban Grpc.Tools.
Kód létrehozása előre
Az egyik megoldás a kód idő előtti létrehozása.
- Helyezze át a
.protofájlokat és aGrpc.Toolscsomaghivatkozást egy új projektbe. - Tegye közzé a projektet NuGet-csomagként, és töltse fel egy NuGet-hírcsatornába.
- Frissítse az alkalmazást a NuGet-csomagra való hivatkozáshoz.
Az előző lépésekkel az alkalmazásnak már nem kell buildelést végrehajtania Grpc.Tools , mert a kód előre létrejön.
Natív bináris fájlok testreszabása Grpc.Tools
Grpc.Tools támogatja az egyéni natív bináris fájlok használatát. Ez a funkció lehetővé teszi, hogy a gRPC-eszközök olyan környezetekben fussanak, amelyben a natív bináris fájlok kötegei nem támogatottak.
Készítse el vagy szerezze be a protoc és grpc_csharp_plugin natív binárisokat, és konfigurálja a Grpc.Tools azok használatára. Konfigurálja a natív bináris fájlokat a következő környezeti változók beállításával:
-
PROTOBUF_PROTOC- A protokollpufferek fordítójának teljes elérési útja -
GRPC_PROTOC_PLUGIN- A grpc_csharp_plugin teljes elérési útja
Az Alpine Linux esetében a közösség biztosít csomagokat a protokollpufferek fordítójához és a gRPC beépülő modulokhoz a következő helyen: https://pkgs.alpinelinux.org/.
# Build or install the binaries for your architecture.
# For Alpine Linux, the grpc-plugins package can be used.
# See https://pkgs.alpinelinux.org/package/edge/community/x86_64/grpc-plugins
apk add grpc-plugins # Alpine Linux specific package installer
# Set environment variables for the built/installed protoc
# and grpc_csharp_plugin binaries
export PROTOBUF_PROTOC=/usr/bin/protoc
export GRPC_PROTOC_PLUGIN=/usr/bin/grpc_csharp_plugin
# When dotnet build runs, the Grpc.Tools NuGet package
# uses the binaries pointed to by the environment variables.
dotnet build
A nem támogatott architektúrák használatával Grpc.Tools kapcsolatos további információkért tekintse meg a gRPC buildintegrációs dokumentációját.
gRPC-hívás időtúllépése innen: HttpClient.Timeout
HttpClient alapértelmezés szerint 100 másodperces időtúllépéssel van konfigurálva. Ha a GrpcChannel úgy van konfigurálva, hogy egy HttpClient-et használjon, a hosszú ideig futó gRPC-streamhívásokat megszakítják, ha nem fejeződnek be az időkorláton belül.
System.OperationCanceledException: The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
Ezt a hibát többféleképpen is kijavíthatja. Az első lépés HttpClient.Timeout nagyobb értékre való konfigurálása. Timeout.InfiniteTimeSpan kikapcsolja az időkorlátot.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(handler) { Timeout = Timeout.InfiniteTimeSpan };
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greeter.GreeterClient(channel);
Másik lehetőségként kerülje HttpClient létrehozását és helyette állítsa be GrpcChannel.HttpHandler-et.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);
Ez a dokumentum a gRPC-alkalmazások .NET-en való fejlesztése során gyakran előforduló problémákat ismerteti.
Eltérés az ügyfél és a szolgáltatás SSL-/TLS-konfigurációja között
A gRPC-sablon és -minták a Transport Layer Security (TLS) használatával biztosítják alapértelmezés szerint a gRPC-szolgáltatásokat. A gRPC-ügyfeleknek biztonságos kapcsolatot kell használniuk a biztonságos gRPC-szolgáltatások sikeres meghívásához.
Ellenőrizheti, hogy a ASP.NET Core gRPC szolgáltatás TLS-t használ-e az alkalmazás indításakor írt naplókban. A szolgáltatás egy HTTPS-végpontot figyel:
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
A .NET-ügyfélnek a kiszolgáló címében kell használnia https a hívások biztonságos kapcsolattal való indításához:
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);
}
Minden gRPC-ügyfél-implementáció támogatja a TLS-t. A más nyelvekről származó gRPC-ügyfelek általában megkövetelik a csatorna konfigurálását SslCredentials.
SslCredentials Meghatározza az ügyfél által használandó tanúsítványt, és azt a nem biztonságos hitelesítő adatok helyett kell használni. Példák a különböző gRPC-ügyfél-implementációk TLS használatára való konfigurálására: gRPC-hitelesítés.
gRPC szolgáltatás meghívása nem megbízható/érvénytelen tanúsítvánnyal
A .NET gRPC-ügyfél megköveteli, hogy a szolgáltatás megbízható tanúsítvánnyal rendelkezzen. A rendszer a következő hibaüzenetet adja vissza, ha megbízható tanúsítvány nélkül hív meg egy gRPC-szolgáltatást:
Kezeletlen kivétel. System.Net.Http.HttpRequestException: Az SSL-kapcsolat nem hozható létre, lásd a belső kivételt. >--- System.Security.Authentication.AuthenticationException: A távoli tanúsítvány érvénytelen az érvényesítési eljárásnak megfelelően.
Ez a hiba akkor jelenhet meg, ha helyileg teszteli az alkalmazást, és a ASP.NET Core HTTPS fejlesztési tanúsítvány nem megbízható. A probléma megoldására vonatkozó utasításokért tekintse meg a ASP.NET Core HTTPS fejlesztői tanúsítvány megbízhatóságát Windows és macOS rendszeren.
Ha egy gRPC-szolgáltatást hív meg egy másik gépen, és nem tud megbízni a tanúsítványban, akkor a gRPC-ügyfél konfigurálható úgy, hogy figyelmen kívül hagyja az érvénytelen tanúsítványt. A következő kód a megbízható tanúsítvány nélküli hívások engedélyezésére szolgál HttpClientHandler.ServerCertificateCustomValidationCallback :
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
A gRPC-ügyfél-előállító megbízható tanúsítvány nélkül engedélyezi a hívásokat. ConfigurePrimaryHttpMessageHandler A bővítménymetódus használatával konfigurálja a kezelőt az ügyfélen:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
return handler;
});
Warning
A nem megbízható tanúsítványokat csak az alkalmazásfejlesztés során szabad használni. A gyártásban lévő alkalmazásoknak mindig érvényes tanúsítványokat kell használniuk.
Nem biztonságos gRPC-szolgáltatások hívása .NET-ügyféllel
A .NET gRPC-ügyfél biztonság nélküli gRPC-szolgáltatásokat hívhat meg a kiszolgáló címének http megadásával. Például: GrpcChannel.ForAddress("http://localhost:5000").
Az alkalmazás által használt .NET-verziótól függően további követelmények vonatkoznak a nem biztonságos gRPC-szolgáltatások meghívására:
A .NET 5 vagy újabb verziójához a Grpc.Net.Client 2.32.0-s vagy újabb verziója szükséges.
A .NET Core 3.x további konfigurációt igényel. Az alkalmazásnak a következőre kell beállítania a
System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupportkapcsolóttrue:// 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);
A System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport kapcsoló csak a .NET Core 3.x-hez szükséges. Nem tesz semmit a .NET 5-ben, és nem szükséges.
Important
A nem biztonságos gRPC-szolgáltatásokat http/2-csak porton kell üzemeltetni. További információ: ASP.NET Core protokoll egyeztetése.
Nem indítható el ASP.NET Core gRPC-alkalmazás macOS rendszeren
Kestrel nem támogatja a HTTP/2-t a tLS-sel macOS rendszeren a .NET 8 előtt. A ASP.NET Core gRPC-sablon és -minták alapértelmezés szerint TLS-t használnak. A gRPC-kiszolgáló indításakor a következő hibaüzenet jelenik meg:
Nem lehet csatlakozni https://localhost:5001 az IPv4-visszacsatolási felületen: "A HTTP/2 TLS-en keresztül nem támogatott macOS rendszeren, mert hiányzik az ALPN-támogatás."
A probléma megoldásához a .NET 7 vagy korábbi verzióiban konfigurálja a Kestrel és a gRPC-ügyfelet a HTTP/2 TLS nélküli használatára. Ezt csak a fejlesztés során szabad elvégeznie. A TLS használatának mellőzése esetén a gRPC-üzenetek titkosítás nélkül lesznek elküldve.
Kestrel HTTP/2-végpontot kell konfigurálnia TLS nélkül a következőben 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>();
});
Ha egy HTTP/2-végpont TLS nélkül van konfigurálva, a végpont ListenOptions.Protokolljait a következőre HttpProtocols.Http2kell állítani: .
HttpProtocols.Http1AndHttp2 nem használható, mert a HTTP/2 egyeztetéséhez TLS szükséges. TLS nélkül a végponthoz való összes kapcsolat alapértelmezés szerint HTTP/1.1, és a gRPC-hívások sikertelenek.
A gRPC-ügyfelet úgy is konfigurálnia kell, hogy ne használja a TLS-t. További információ: Nem biztonságos gRPC-szolgáltatások meghívása .NET-ügyféllel.
Warning
A HTTP/2 TLS nélkül csak az alkalmazásfejlesztés során használható. Az éles alkalmazásoknak mindig az átviteli biztonságot kell használniuk. További információkért tekintse meg a ASP.NET Core-ra vonatkozó gRPC biztonsági szempontjait.
A gRPC C#-objektumok nem fájlokból .proto generált kód
A konkrét ügyfelek és a szolgáltatásbázis-osztályok gRPC-kódgenerálásához protobuf fájlokat és eszközöket kell hivatkozni egy projektből. A következőket kell tartalmaznia:
-
.protoaz elemcsoportban<Protobuf>használni kívánt fájlok. Az importált.protofájlokra a projektnek hivatkoznia kell. - Csomaghivatkozás a Grpc.Tools gRPC eszközcsomagra.
A gRPC C#-eszközök létrehozásával kapcsolatos további információkért lásd a GRPC-szolgáltatásokat a C#-tal.
A gRPC-szolgáltatásokat üzemeltető ASP.NET Core-webalkalmazásnak csak a létrehozott alapszolgáltatás-osztályra van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
A gRPC-hívásokat kezdeményező gRPC-ügyfélalkalmazásnak csak a létrehozott konkrét ügyfélre van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
A WPF-projektek nem tudnak gRPC C#-objektumokat létrehozni fájlokból .proto
A WPF-projektek ismert problémával rendelkeznek, amely megakadályozza a gRPC-kódlétrehozást a megfelelő működésben. A WPF projektben a Grpc.Tools és .proto fájlokra való hivatkozással generált gRPC-típusok fordítási hibákat okoznak a használat során.
CS0246-os hiba: A "MyGrpcServices" típus- vagy névtérnév nem található (hiányzik egy felhasználói irányelv vagy egy szerelvényhivatkozás?)
A problémát a következő módon lehet megkerülni:
- Hozzon létre egy új .NET-osztálytárprojektet.
- Az új projektben adjon hozzá hivatkozásokat a C#-kód fájlokból való
.protolétrehozásának engedélyezéséhez:- Adja hozzá a következő csomaghivatkozásokat:
- Adj hozzá
.protofájlokat az<Protobuf>elemcsoporthoz.
- A WPF-alkalmazásban adjon hozzá egy hivatkozást az új projekthez.
A WPF-alkalmazás használhatja az új osztálytárprojektből létrehozott gRPC-típusokat.
Alkönyvtárban üzemeltetett gRPC-szolgáltatások meghívása
Warning
Számos külső gRPC-eszköz nem támogatja az alkönyvtárakban üzemeltetett szolgáltatásokat. Fontolja meg a gRPC gyökérkönyvtárként való üzemeltetésének módját.
A gRPC-csatorna címének elérési útösszetevőjét a rendszer figyelmen kívül hagyja a gRPC-hívások során. Nem használható GrpcChannel.ForAddress("https://localhost:5001/ignored_path") például a ignored_path szolgáltatáshoz tartozó gRPC-hívások útválasztása során.
A cím elérési útja figyelmen kívül lesz hagyva, mert a gRPC szabványosított, előíró címstruktúrával rendelkezik. A gRPC-címek egyesítik a csomag, a szolgáltatás és a metódus nevét: https://localhost:5001/PackageName.ServiceName/MethodName.
Vannak olyan esetek, amikor egy alkalmazásnak gRPC-hívásokkal kell tartalmaznia egy elérési utat. Ha például egy ASP.NET Core gRPC-alkalmazást üzemeltetnek egy IIS-címtárban, és a címtárat bele kell foglalni a kérésbe. Ha egy elérési út szükséges, az alábbi egyéni SubdirectoryHandler beállítással adható hozzá a gRPC-híváshoz:
/// <summary>
/// A delegating handler that adds a subdirectory to the URI of gRPC requests.
/// </summary>
public class SubdirectoryHandler : DelegatingHandler
{
private readonly string _subdirectory;
public SubdirectoryHandler(HttpMessageHandler innerHandler, string subdirectory)
: base(innerHandler)
{
_subdirectory = subdirectory;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var old = request.RequestUri;
var url = $"{old.Scheme}://{old.Host}:{old.Port}";
url += $"{_subdirectory}{request.RequestUri.AbsolutePath}";
request.RequestUri = new Uri(url, UriKind.Absolute);
return base.SendAsync(request, cancellationToken);
}
}
SubdirectoryHandler a gRPC-csatorna létrehozásakor használatos.
var handler = new SubdirectoryHandler(new HttpClientHandler(), "/MyApp");
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
Az előző kód:
- Létrehoz egy
SubdirectoryHandlera/MyAppelérési úttal. - Konfigurál egy csatornát a
SubdirectoryHandlerhasználatára. - Meghívja a gRPC szolgáltatást a következővel
SayHelloAsync: . A gRPC-hívást a rendszer elküldi a következőnekhttps://localhost:5001/MyApp/greet.Greeter/SayHello: .
Másik lehetőségként egy ügyfél gyártói is konfigurálható SubdirectoryHandlerAddHttpMessageHandler használatával.
gRPC-hívás időtúllépése innen: HttpClient.Timeout
HttpClient alapértelmezés szerint 100 másodperces időtúllépéssel van konfigurálva. Ha a GrpcChannel úgy van konfigurálva, hogy egy HttpClient-et használjon, a hosszú ideig futó gRPC-streamhívásokat megszakítják, ha nem fejeződnek be az időkorláton belül.
System.OperationCanceledException: The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
Ezt a hibát többféleképpen is kijavíthatja. Az első lépés HttpClient.Timeout nagyobb értékre való konfigurálása. Timeout.InfiniteTimeSpan kikapcsolja az időkorlátot.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(handler) { Timeout = Timeout.InfiniteTimeSpan };
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greeter.GreeterClient(channel);
Másik lehetőségként kerülje HttpClient létrehozását és helyette állítsa be GrpcChannel.HttpHandler-et.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);
Ez a dokumentum a gRPC-alkalmazások .NET-en való fejlesztése során gyakran előforduló problémákat ismerteti.
Eltérés az ügyfél és a szolgáltatás SSL-/TLS-konfigurációja között
A gRPC-sablon és -minták a Transport Layer Security (TLS) használatával biztosítják alapértelmezés szerint a gRPC-szolgáltatásokat. A gRPC-ügyfeleknek biztonságos kapcsolatot kell használniuk a biztonságos gRPC-szolgáltatások sikeres meghívásához.
Ellenőrizheti, hogy a ASP.NET Core gRPC szolgáltatás TLS-t használ-e az alkalmazás indításakor írt naplókban. A szolgáltatás egy HTTPS-végpontot figyel:
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
A .NET-ügyfélnek a kiszolgáló címében kell használnia https a hívások biztonságos kapcsolattal való indításához:
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);
}
Minden gRPC-ügyfél-implementáció támogatja a TLS-t. A más nyelvekről származó gRPC-ügyfelek általában megkövetelik a csatorna konfigurálását SslCredentials.
SslCredentials Meghatározza az ügyfél által használandó tanúsítványt, és azt a nem biztonságos hitelesítő adatok helyett kell használni. Példák a különböző gRPC-ügyfél-implementációk TLS használatára való konfigurálására: gRPC-hitelesítés.
gRPC szolgáltatás meghívása nem megbízható/érvénytelen tanúsítvánnyal
A .NET gRPC-ügyfél megköveteli, hogy a szolgáltatás megbízható tanúsítvánnyal rendelkezzen. A rendszer a következő hibaüzenetet adja vissza, ha megbízható tanúsítvány nélkül hív meg egy gRPC-szolgáltatást:
Kezeletlen kivétel. System.Net.Http.HttpRequestException: Az SSL-kapcsolat nem hozható létre, lásd a belső kivételt. >--- System.Security.Authentication.AuthenticationException: A távoli tanúsítvány érvénytelen az érvényesítési eljárásnak megfelelően.
Ez a hiba akkor jelenhet meg, ha helyileg teszteli az alkalmazást, és a ASP.NET Core HTTPS fejlesztési tanúsítvány nem megbízható. A probléma megoldására vonatkozó utasításokért tekintse meg a ASP.NET Core HTTPS fejlesztői tanúsítvány megbízhatóságát Windows és macOS rendszeren.
Ha egy gRPC-szolgáltatást hív meg egy másik gépen, és nem tud megbízni a tanúsítványban, akkor a gRPC-ügyfél konfigurálható úgy, hogy figyelmen kívül hagyja az érvénytelen tanúsítványt. A következő kód a megbízható tanúsítvány nélküli hívások engedélyezésére szolgál HttpClientHandler.ServerCertificateCustomValidationCallback :
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
A gRPC-ügyfél-előállító megbízható tanúsítvány nélkül engedélyezi a hívásokat. ConfigurePrimaryHttpMessageHandler A bővítménymetódus használatával konfigurálja a kezelőt az ügyfélen:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
return handler;
});
Warning
A nem megbízható tanúsítványokat csak az alkalmazásfejlesztés során szabad használni. A gyártásban lévő alkalmazásoknak mindig érvényes tanúsítványokat kell használniuk.
Nem biztonságos gRPC-szolgáltatások hívása .NET-ügyféllel
A .NET gRPC-ügyfél biztonság nélküli gRPC-szolgáltatásokat hívhat meg a kiszolgáló címének http megadásával. Például: GrpcChannel.ForAddress("http://localhost:5000").
Az alkalmazás által használt .NET-verziótól függően további követelmények vonatkoznak a nem biztonságos gRPC-szolgáltatások meghívására:
A .NET 5 vagy újabb verziójához a Grpc.Net.Client 2.32.0-s vagy újabb verziója szükséges.
A .NET Core 3.x további konfigurációt igényel. Az alkalmazásnak a következőre kell beállítania a
System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupportkapcsolóttrue:// 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);
A System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport kapcsoló csak a .NET Core 3.x-hez szükséges. Nem tesz semmit a .NET 5-ben, és nem szükséges.
Important
A nem biztonságos gRPC-szolgáltatásokat http/2-csak porton kell üzemeltetni. További információ: ASP.NET Core protokoll egyeztetése.
Nem indítható el ASP.NET Core gRPC-alkalmazás macOS rendszeren
Kestrel nem támogatja a HTTP/2-t a tLS-sel macOS rendszeren a .NET 8 előtt. A ASP.NET Core gRPC-sablon és -minták alapértelmezés szerint TLS-t használnak. A gRPC-kiszolgáló indításakor a következő hibaüzenet jelenik meg:
Nem lehet csatlakozni https://localhost:5001 az IPv4-visszacsatolási felületen: "A HTTP/2 TLS-en keresztül nem támogatott macOS rendszeren, mert hiányzik az ALPN-támogatás."
A probléma megoldásához a .NET 7 vagy korábbi verzióiban konfigurálja a Kestrel és a gRPC-ügyfelet a HTTP/2 TLS nélküli használatára. Ezt csak a fejlesztés során szabad elvégeznie. A TLS használatának mellőzése esetén a gRPC-üzenetek titkosítás nélkül lesznek elküldve.
Kestrel HTTP/2-végpontot kell konfigurálnia TLS nélkül a következőben 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>();
});
Ha egy HTTP/2-végpont TLS nélkül van konfigurálva, a végpont ListenOptions.Protokolljait a következőre HttpProtocols.Http2kell állítani: .
HttpProtocols.Http1AndHttp2 nem használható, mert a HTTP/2 egyeztetéséhez TLS szükséges. TLS nélkül a végponthoz való összes kapcsolat alapértelmezés szerint HTTP/1.1, és a gRPC-hívások sikertelenek.
A gRPC-ügyfelet úgy is konfigurálnia kell, hogy ne használja a TLS-t. További információ: Nem biztonságos gRPC-szolgáltatások meghívása .NET-ügyféllel.
Warning
A HTTP/2 TLS nélkül csak az alkalmazásfejlesztés során használható. Az éles alkalmazásoknak mindig az átviteli biztonságot kell használniuk. További információkért tekintse meg a ASP.NET Core-ra vonatkozó gRPC biztonsági szempontjait.
A gRPC C#-objektumok nem fájlokból .proto generált kód
A konkrét ügyfelek és a szolgáltatásbázis-osztályok gRPC-kódgenerálásához protobuf fájlokat és eszközöket kell hivatkozni egy projektből. A következőket kell tartalmaznia:
-
.protoaz elemcsoportban<Protobuf>használni kívánt fájlok. Az importált.protofájlokra a projektnek hivatkoznia kell. - Csomaghivatkozás a Grpc.Tools gRPC eszközcsomagra.
A gRPC C#-eszközök létrehozásával kapcsolatos további információkért lásd a GRPC-szolgáltatásokat a C#-tal.
A gRPC-szolgáltatásokat üzemeltető ASP.NET Core-webalkalmazásnak csak a létrehozott alapszolgáltatás-osztályra van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
A gRPC-hívásokat kezdeményező gRPC-ügyfélalkalmazásnak csak a létrehozott konkrét ügyfélre van szüksége:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
A WPF-projektek nem tudnak gRPC C#-objektumokat létrehozni fájlokból .proto
A WPF-projektek ismert problémával rendelkeznek, amely megakadályozza a gRPC-kódlétrehozást a megfelelő működésben. A WPF projektben a Grpc.Tools és .proto fájlokra való hivatkozással generált gRPC-típusok fordítási hibákat okoznak a használat során.
CS0246-os hiba: A "MyGrpcServices" típus- vagy névtérnév nem található (hiányzik egy felhasználói irányelv vagy egy szerelvényhivatkozás?)
A problémát a következő módon lehet megkerülni:
- Hozzon létre egy új .NET-osztálytárprojektet.
- Az új projektben adjon hozzá hivatkozásokat a C#-kód fájlokból való
.protolétrehozásának engedélyezéséhez:- Adja hozzá a következő csomaghivatkozásokat:
- Adj hozzá
.protofájlokat az<Protobuf>elemcsoporthoz.
- A WPF-alkalmazásban adjon hozzá egy hivatkozást az új projekthez.
A WPF-alkalmazás használhatja az új osztálytárprojektből létrehozott gRPC-típusokat.
Alkönyvtárban üzemeltetett gRPC-szolgáltatások meghívása
Warning
Számos külső gRPC-eszköz nem támogatja az alkönyvtárakban üzemeltetett szolgáltatásokat. Fontolja meg a gRPC gyökérkönyvtárként való üzemeltetésének módját.
A gRPC-csatorna címének elérési útösszetevőjét a rendszer figyelmen kívül hagyja a gRPC-hívások során. Nem használható GrpcChannel.ForAddress("https://localhost:5001/ignored_path") például a ignored_path szolgáltatáshoz tartozó gRPC-hívások útválasztása során.
A cím elérési útja figyelmen kívül lesz hagyva, mert a gRPC szabványosított, előíró címstruktúrával rendelkezik. A gRPC-címek egyesítik a csomag, a szolgáltatás és a metódus nevét: https://localhost:5001/PackageName.ServiceName/MethodName.
Vannak olyan esetek, amikor egy alkalmazásnak gRPC-hívásokkal kell tartalmaznia egy elérési utat. Ha például egy ASP.NET Core gRPC-alkalmazást üzemeltetnek egy IIS-címtárban, és a címtárat bele kell foglalni a kérésbe. Ha egy elérési út szükséges, az alábbi egyéni SubdirectoryHandler beállítással adható hozzá a gRPC-híváshoz:
/// <summary>
/// A delegating handler that adds a subdirectory to the URI of gRPC requests.
/// </summary>
public class SubdirectoryHandler : DelegatingHandler
{
private readonly string _subdirectory;
public SubdirectoryHandler(HttpMessageHandler innerHandler, string subdirectory)
: base(innerHandler)
{
_subdirectory = subdirectory;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var old = request.RequestUri;
var url = $"{old.Scheme}://{old.Host}:{old.Port}";
url += $"{_subdirectory}{request.RequestUri.AbsolutePath}";
request.RequestUri = new Uri(url, UriKind.Absolute);
return base.SendAsync(request, cancellationToken);
}
}
SubdirectoryHandler a gRPC-csatorna létrehozásakor használatos.
var handler = new SubdirectoryHandler(new HttpClientHandler(), "/MyApp");
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions { HttpHandler = handler });
var client = new Greet.GreeterClient(channel);
var reply = await client.SayHelloAsync(new HelloRequest { Name = ".NET" });
Az előző kód:
- Létrehoz egy
SubdirectoryHandlera/MyAppelérési úttal. - Konfigurál egy csatornát a
SubdirectoryHandlerhasználatára. - Meghívja a gRPC szolgáltatást a következővel
SayHelloAsync: . A gRPC-hívást a rendszer elküldi a következőnekhttps://localhost:5001/MyApp/greet.Greeter/SayHello: .
Másik lehetőségként egy ügyfél gyártói is konfigurálható SubdirectoryHandlerAddHttpMessageHandler használatával.
gRPC-hívás időtúllépése innen: HttpClient.Timeout
HttpClient alapértelmezés szerint 100 másodperces időtúllépéssel van konfigurálva. Ha a GrpcChannel úgy van konfigurálva, hogy egy HttpClient-et használjon, a hosszú ideig futó gRPC-streamhívásokat megszakítják, ha nem fejeződnek be az időkorláton belül.
System.OperationCanceledException: The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing.
Ezt a hibát többféleképpen is kijavíthatja. Az első lépés HttpClient.Timeout nagyobb értékre való konfigurálása. Timeout.InfiniteTimeSpan kikapcsolja az időkorlátot.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(handler) { Timeout = Timeout.InfiniteTimeSpan };
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greeter.GreeterClient(channel);
Másik lehetőségként kerülje HttpClient létrehozását és helyette állítsa be GrpcChannel.HttpHandler-et.
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var channel = GrpcChannel.ForAddress("https://localhost:5001",
new GrpcChannelOptions { HttpHandler = handler });
var client = new Greeter.GreeterClient(channel);