Condividi tramite


Comunicazione tra processi con gRPC e named pipe

Di James Newton-King

.NET supporta la comunicazione tra processi (IPC) tramite gRPC. Per altre informazioni sull'uso di gRPC per comunicare tra processi, vedere Comunicazione tra processi con gRPC.

Named pipe è un trasporto IPC supportato in tutte le versioni di Windows. Le named pipe si integrano bene con la sicurezza di Windows per controllare l'accesso client alla pipe. Questo articolo illustra come configurare la comunicazione gRPC tramite named pipe.

Prerequisiti

  • .NET 8 o versione successiva
  • Finestre

Configurazione del server

Le named pipe sono supportate da Kestrel, che è configurato in Program.cs:

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenNamedPipe("MyPipeName", listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http2;
    });
});

L'esempio precedente:

  • Configura gli Kestrelendpoint in ConfigureKestrel.
  • Chiama ListenNamedPipe per ascoltare una named pipe con il nome specificato.
  • Crea un endpoint named pipe che non è configurato per l'uso di HTTPS. Per informazioni sull'abilitazione di HTTPS, vedere Kestrel Configurazione dell'endpoint HTTPS.

Configurazione del client

GrpcChannel supporta l'esecuzione di chiamate gRPC su trasporti personalizzati. Quando viene creato un canale, può essere configurato con un SocketsHttpHandler oggetto con un oggetto personalizzato ConnectCallback. Il callback consente al client di effettuare connessioni su trasporti personalizzati e quindi inviare richieste HTTP su tale trasporto.

Nota

Alcune funzionalità di connettività di GrpcChannel, ad esempio il bilanciamento del carico lato client e lo stato del canale, non possono essere usate insieme alle named pipe.

Esempio di factory di connessione named pipe:

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;
        }
    }
}

Uso della factory di connessione personalizzata per creare un canale:

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
    });
}

Canali creati usando il codice precedente inviano chiamate gRPC su named pipe.