Prozessübergreifende Kommunikation mit gRPC und Named Pipes
.NET unterstützt die prozessübergreifende Kommunikation (Inter-Process Communication, IPC) mithilfe von gRPC. Weitere Informationen zu den ersten Schritten mit der Verwendung von gRPC für die Kommunikation zwischen Prozessen finden Sie unter Inter-Process Communication mit gRPC.
Named Pipes sind ein IPC-Transport, der in allen Versionen von Windows unterstützt wird. Named Pipes sind gut in die Windows-Sicherheit integriert, um den Clientzugriff auf die Pipe zu steuern. In diesem Artikel wird erläutert, wie Sie die gRPC-Kommunikation über Named Pipes konfigurieren.
Voraussetzungen
- .NET 8 oder höher
- Windows
Serverkonfiguration
Named Pipes werden von Kestrel unterstützt. Die Konfiguration erfolgt in Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenNamedPipe("MyPipeName", listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
Für das vorherige Beispiel gilt Folgendes:
- Der Endpunkt von Kestrel wird in ConfigureKestrel konfiguriert.
- Ruft
ListenNamedPipe
auf, um auf eine Named Pipe mit dem angegebenen Namen zu lauschen. - Erstellt einen Named Pipe-Endpunkt, der nicht für die Verwendung von HTTPS konfiguriert ist. Informationen zum Aktivieren von HTTPS finden Sie unter Kestrel-HTTPS-Endpunktkonfiguration.
Clientkonfiguration
GrpcChannel
unterstützt gRPC-Aufrufe für benutzerdefinierte Datentransporte. Wenn ein Kanal erstellt wird, kann er mit einer SocketsHttpHandler-Klasse konfiguriert werden, die über ein benutzerdefiniertes ConnectCallback-Objekt verfügt. Der Rückruf ermöglicht es dem Client, Verbindungen für benutzerdefinierte Datentransporte herzustellen und dann HTTP-Anforderungen über diese Datentransporte zu senden.
Hinweis
Einige Konnektivitätsfeatures von GrpcChannel
, wie clientseitiger Lastenausgleich und Kanalstatus, können nicht zusammen mit Named Pipes verwendet werden.
Beispiel für eine Named Pipes-Verbindungsfactory:
public class NamedPipesConnectionFactory
{
private readonly string pipeName;
public NamedPipesConnectionFactory(string pipeName)
{
this.pipeName = pipeName;
}
public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
CancellationToken cancellationToken = default)
{
var clientStream = new NamedPipeClientStream(
serverName: ".",
pipeName: this.pipeName,
direction: PipeDirection.InOut,
options: PipeOptions.WriteThrough | PipeOptions.Asynchronous,
impersonationLevel: TokenImpersonationLevel.Anonymous);
try
{
await clientStream.ConnectAsync(cancellationToken).ConfigureAwait(false);
return clientStream;
}
catch
{
clientStream.Dispose();
throw;
}
}
}
So wird die benutzerdefinierte Verbindungsfactory zum Erstellen eines Kanals verwendet:
public static GrpcChannel CreateChannel()
{
var connectionFactory = new NamedPipesConnectionFactory("MyPipeName");
var socketsHttpHandler = new SocketsHttpHandler
{
ConnectCallback = connectionFactory.ConnectAsync
};
return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler
});
}
Kanäle, die mithilfe des vorangehenden Codes erstellt werden, senden gRPC-Aufrufe über Named Pipes.