.NET Core 'da gRPC sorunlarını giderme
Bu belgede, .NET üzerinde gRPC uygulamaları geliştirirken yaygın olarak karşılaşılan sorunlar ele alınmaktadır.
İstemci ve hizmet SSL/TLS yapılandırması arasında uyuşmazlık
GRPC şablonu ve örnekleri, varsayılan olarak gRPC hizmetlerini güvenli hale getirmek için Aktarım Katmanı Güvenliği 'ni (TLS) kullanır. gRPC istemcilerinin güvenli gRPC hizmetlerini başarıyla çağırması için güvenli bir bağlantı kullanması gerekir.
ASP.NET Core gRPC hizmetinin uygulama başlatma bölümünde yazılan günlüklerde TLS kullandığını doğrulayabilirsiniz. Hizmet bir HTTPS uç noktasını dinleyerek:
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 istemcisinin, https güvenli bir bağlantıyla çağrı yapmak için sunucu adresinde kullanması gerekir:
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);
}
Tüm gRPC istemci uygulamaları TLS 'yi destekler. diğer dillerden gRPC istemcileri, genellikle kanalı ile yapılandırılmış olmasını gerektirir SslCredentials . SslCredentials İstemcinin kullanacağı sertifikayı belirtir ve güvenli olmayan kimlik bilgileri yerine kullanılması gerekir. Farklı gRPC istemci uygulamalarını TLS kullanmak üzere yapılandırma örnekleri için bkz. GRPC kimlik doğrulaması.
Güvenilir olmayan/geçersiz sertifikayla gRPC hizmetini çağırma
.NET gRPC istemcisi hizmetin güvenilen sertifikaya sahip olmasını gerektirir. Bir gRPC hizmeti güvenilir bir sertifika olmadan çağrılırken aşağıdaki hata iletisi döndürülür:
İşlenmeyen özel durum. System .net. http. HttpRequestException: SSL bağlantısı kurulamadı, iç özel duruma bakın. ---> System.Security.Authentication.AuthenticationException: Doğrulama yordamına göre uzak sertifika geçersiz.
Yerel olarak test ediyorsanız ve ASP.NET Core HTTPS geliştirme sertifikasına güvenilmiyorsa bu hatayı alabilirsiniz. Bu sorunu düzeltmeye ilişkin yönergeler için bkz. Windows ASP.NET macOS'taASP.NET Core HTTPS geliştirme sertifikasına güvenin.
Başka bir makinede gRPC hizmetini çağırıyorsanız ve sertifikaya güvenemiyorsanız, gRPC istemcisi geçersiz sertifikayı yoksaymak üzere yalıtabilirsiniz. Aşağıdaki kod, güvenilir bir sertifika olmadan çağrılara izin vermek için HttpClientHandler.ServerCertificateCustomValidationCallback kullanır:
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);
Uyarı
Güvenilmeyen sertifikalar yalnızca uygulama geliştirme sırasında kullanılmalıdır. Üretim uygulamaları her zaman geçerli sertifikalar kullan olmalıdır.
.NET Core istemcisiyle güvenli olmayan gRPC hizmetlerini çağırma
.NET gRPC istemcisi, sunucu adresine göre tahminde bulundurarak güvenli olmayan gRPC http hizmetlerini çağırabilirsiniz. Örneğin, GrpcChannel.ForAddress("http://localhost:5000").
Bir uygulamanın kullanmakta olduğu .NET sürümüne bağlı olarak güvenli olmayan gRPC hizmetlerini çağırmaya bazı ek gereksinimler vardır:
.NET 5 veya sonraki sürümler için Grpc.Net.Client 2.32.0 veya sonraki bir sürümü gerekir.
.NET Core 3.x için ek yapılandırma gerekir. Uygulamanın anahtarını olarak
System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupportayarlamasıtruegerekir:// 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);
Anahtar System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport yalnızca .NET Core 3.x için gereklidir. .NET 5'te hiçbir şey yapmadı ve gerekli değildir.
macOS'ASP.NET Core gRPC uygulaması başlatamıyor
Kestrel macOS'ta TLS ile HTTP/2'yi ve Windows 7 gibi eski Windows sürümlerini desteklemez. ASP.NET Core gRPC şablonu ve örnekleri varsayılan olarak TLS kullanır. gRPC sunucusunu başlatmaya çalışırken aşağıdaki hata iletisini alırsınız:
IPv4 geri döngü arabiriminde ile bağlantı https://localhost:5001 açamıyor: 'TLS üzerinden HTTP/2, macOS'ta EKSIK OLAN ÇÜNKÜİPN desteği nedeniyle desteklenmiyor.'.
Bu sorunu gidermek için ve Kestrel gRPC istemcisini TLS olmadan HTTP/2'yi kullanmak üzere yapılandırabilirsiniz. Bunu yalnızca geliştirme sırasında yapacaktır. TLS'nin kullanılamayacak olması gRPC iletilerinin şifreleme olmadan gönderilir.
Kestrel, Program.cs içinde TLS olmadan bir HTTP/2 uç noktası yapılandırmalı:
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>();
});
BIR HTTP/2 uç noktası TLS olmadan yapılandırıldığında, uç noktanın ListenOptions.Protocols'un olarak ayarlanmış olması HttpProtocols.Http2 gerekir. HttpProtocols.Http1AndHttp2 HTTP/2 anlaşması yapmak için TLS gerektiğinden kullanılamaz. TLS olmadan uç noktasına yapılan tüm bağlantılar varsayılan olarak HTTP/1.1 ve gRPC çağrıları başarısız olur.
BIR HTTP/2 uç noktası TLS olmadan yapılandırıldığında, uç noktanın ListenOptions.Protocols'un olarak ayarlanmış olması HttpProtocols.Http2 gerekir. HttpProtocols.Http1AndHttp2 HTTP/2 anlaşması yapmak için TLS gerektiğinden kullanılamaz. TLS olmadan uç noktasına yapılan tüm bağlantılar varsayılan olarak HTTP/1.1 ve gRPC çağrıları başarısız olur.
gRPC istemcisinin TLS kullanmayacak şekilde de yapılandırılması gerekir. Daha fazla bilgi için bkz. .NET Core istemcisi ile güvenli olmayan gRPC hizmetlerini çağırma.
Uyarı
TLS olmadan HTTP/2 yalnızca uygulama geliştirme sırasında kullanılmalıdır. Üretim uygulamaları her zaman aktarım güvenliğini kullanlı. Daha fazla bilgi için bkz. ASP.NET Core için gRPC'de güvenlik konuları.
gRPC C# varlıkları .proto dosyalarından oluşturulan kod değildir
Somut istemcilerin ve hizmet temel sınıflarının gRPC kod oluşturması için bir projeden protobuf dosyalarına ve araçlara başvurulabilir. Şunları dahil etmek gerekir:
- Öğe grubunda kullanmak istediğiniz .proto
<Protobuf>dosyaları. İçe aktarılan .proto dosyalarına proje tarafından başvurulları gerekir. - GRPC araç paketi GRPC. Tools'a paket başvurusu.
GRPC C# varlıkları oluşturma hakkında daha fazla bilgi için bkz C# içeren gRPC hizmetleri ..
GRPC hizmetlerini barındıran bir ASP.NET Core Web uygulaması yalnızca oluşturulan hizmet taban sınıfına ihtiyaç duyuyor:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
</ItemGroup>
GRPC çağrısı yapan bir gRPC istemci uygulaması yalnızca somut istemcinin oluşturulması gerekir:
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
</ItemGroup>
WPF projeleri. proto dosyalarından gRPC C# varlıkları oluşturulamıyor
WPF projelerinde, gRPC kod oluşturmanın düzgün çalışmasını engelleyen bilinen bir sorun vardır. Bir WPF projesinde Grpc.Tools , ve . proto dosyalarına başvurarak oluşturulan tüm GRPC türleri, kullanıldığında derleme hataları oluşturur:
hata CS0246: ' MyGrpcServices ' türü veya ad alanı adı bulunamadı (bir using yönergeniz veya derleme başvurunuz mu eksik?)
Bu soruna geçici çözüm olarak şunları yapabilirsiniz:
- Yeni bir .NET Core sınıf kitaplığı projesi oluşturun.
- Yeni projede, * . proto dosyalarından C# kod üretiminietkinleştirmek için başvurular ekleyin:
- Aşağıdaki paket başvurularını ekleyin:
- * . Proto dosyalarını
<Protobuf>öğe grubuna ekleyin.
- WPF uygulamasında yeni projeye bir başvuru ekleyin.
WPF uygulaması, yeni sınıf kitaplığı projesinden gRPC tarafından oluşturulan türleri kullanabilir.
Alt dizinde barındırılan gRPC hizmetlerini çağırma
GRPC araması yapıldığında, gRPC kanalının adresinin yol bileşeni yok sayılır. Örneğin, GrpcChannel.ForAddress("https://localhost:5001/ignored_path") hizmet için ignored_path gRPC çağrıları yönlendirken kullanmaz.
gRPC standartlaştırılmış, önleyici bir adres yapısına sahip olduğundan adres yolu yoksayılır. gRPC adresi paket, hizmet ve yöntem adlarını birleştirir: https://localhost:5001/PackageName.ServiceName/MethodName .
Bir uygulamanın gRPC çağrılarına sahip bir yol içermesi gereken bazı senaryolar vardır. Örneğin, bir ASP.NET Core gRPC uygulaması bir IIS dizininde barındırıldı ve dizinin i isteğine dahil olması gerekir. Bir yol gerektiğinde, aşağıda belirtilen özel kullanılarak gRPC çağrısına SubdirectoryHandler eklenebilir:
/// <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 url = $"{request.RequestUri.Scheme}://{request.RequestUri.Host}";
url += $"{_subdirectory}{request.RequestUri.AbsolutePath}";
request.RequestUri = new Uri(url, UriKind.Absolute);
return base.SendAsync(request, cancellationToken);
}
}
SubdirectoryHandler gRPC kanalı oluşturulduğunda kullanılır.
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" });
Yukarıdaki kod:
- yolu
SubdirectoryHandlerile bir/MyAppoluşturur. - Kullanmak için bir kanal
SubdirectoryHandleryapılandırıyor. - ile gRPC hizmetini
SayHelloAsyncarar. gRPC çağrısı, 'ahttps://localhost:5001/MyApp/greet.Greeter/SayHellogönderilir.
Uyarı
ASP.NET Core GRPC'nin, Azure App Service IIS ile birlikte Azure App Service gerekir. gRPC'nin nerede kullanılabı hakkında daha fazla bilgi için .NET'de desteklenen platformlarda gRPC bkz. .