Komunikacja między procesami za pomocą gRPC i nazwanych potoków
Autor: James Newton-King
Platforma .NET obsługuje komunikację między procesami (IPC) przy użyciu gRPC. Aby uzyskać więcej informacji na temat rozpoczynania pracy z używaniem gRPC do komunikacji między procesami, zobacz Komunikacja między procesami za pomocą usługi gRPC.
Nazwane potoki to transport IPC obsługiwany we wszystkich wersjach systemu Windows. Nazwane potoki dobrze integrują się z zabezpieczeniami systemu Windows, aby kontrolować dostęp klienta do potoku. W tym artykule omówiono sposób konfigurowania komunikacji gRPC za pośrednictwem nazwanych potoków.
Wymagania wstępne
- .NET 8 lub nowszy
- Windows
Konfiguracja serwera
Nazwane potoki są obsługiwane przez Kestrelprogram , który jest skonfigurowany w programie Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenNamedPipe("MyPipeName", listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
Powyższy przykład:
- Konfiguruje Kestrelpunkty końcowe w programie ConfigureKestrel.
- Wywołania
ListenNamedPipe
do nasłuchiwania nazwanego potoku o określonej nazwie. - Tworzy nazwany punkt końcowy potoku, który nie jest skonfigurowany do używania protokołu HTTPS. Aby uzyskać informacje na temat włączania protokołu HTTPS, zobacz Kestrel Konfiguracja punktu końcowego HTTPS.
Konfiguracja klientów
GrpcChannel
obsługuje wykonywanie wywołań gRPC w przypadku transportu niestandardowego. Po utworzeniu kanału można go skonfigurować za pomocą elementu SocketsHttpHandler z niestandardowym ConnectCallbackelementem . Wywołanie zwrotne umożliwia klientowi nawiązywanie połączeń za pośrednictwem transportu niestandardowego, a następnie wysyłanie żądań HTTP za pośrednictwem tego transportu.
Uwaga
Niektóre funkcje łączności programu GrpcChannel
, takie jak równoważenie obciążenia po stronie klienta i stan kanału, nie mogą być używane razem z nazwanymi potokami.
Przykład fabryki połączeń nazwanych potoków:
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;
}
}
}
Tworzenie kanału przy użyciu niestandardowej fabryki połączeń:
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
});
}
Kanały utworzone przy użyciu poprzedniego kodu wysyłają wywołania gRPC za pośrednictwem nazwanych potoków.