Sdílet prostřednictvím


Komunikace mezi procesy pomocí soketů domény gRPC a Unix

Autor: James Newton-King

.NET podporuje komunikaci mezi procesy (IPC) pomocí gRPC. Další informace o tom, jak začít používat gRPC ke komunikaci mezi procesy, najdete v tématu Komunikace mezi procesy s gRPC.

UDS (Unix Domain Sockets) je široce podporovaná přenos IPC, který je efektivnější než TCP, když je klient a server na stejném počítači. Tento článek popisuje, jak nakonfigurovat komunikaci gRPC přes UDS.

Požadavky

Konfigurace serveru

V systémech Unix jsou podporovány Kestrelsokety domény unixu, které jsou nakonfigurovány v Program.cs:

var socketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");

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

Předchozí příklad:

  • Konfiguruje Kestrelkoncové body v ConfigureKestrel.
  • Volání ListenUnixSocket pro naslouchání UDS se zadanou cestou
  • Vytvoří koncový bod UDS, který není nakonfigurovaný tak, aby používal PROTOKOL HTTPS. Informace o povolení PROTOKOLU HTTPS najdete v tématu Kestrel Konfigurace koncového bodu HTTPS.

Konfigurace klienta

GrpcChannel podporuje volání gRPC přes vlastní přenosy. Po vytvoření kanálu je možné ho nakonfigurovat pomocí SocketsHttpHandler vlastního ConnectCallbackkanálu . Zpětné volání umožňuje klientovi vytvářet připojení přes vlastní přenosy a poté odesílat požadavky HTTP přes tento přenos.

Poznámka:

Některé funkce GrpcChannelpřipojení , jako je vyrovnávání zatížení na straně klienta a stav kanálu, se nedají používat společně se sokety domény unixu.

Příklad připojení k doméně unixových soketů:

public class UnixDomainSocketsConnectionFactory
{
    private readonly EndPoint endPoint;

    public UnixDomainSocketsConnectionFactory(EndPoint endPoint)
    {
        this.endPoint = endPoint;
    }

    public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
        CancellationToken cancellationToken = default)
    {
        var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);

        try
        {
            await socket.ConnectAsync(this.endPoint, cancellationToken).ConfigureAwait(false);
            return new NetworkStream(socket, true);
        }
        catch
        {
            socket.Dispose();
            throw;
        }
    }
}

Vytvoření kanálu pomocí vlastní továrny pro připojení:

public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");

public static GrpcChannel CreateChannel()
{
    var udsEndPoint = new UnixDomainSocketEndPoint(SocketPath);
    var connectionFactory = new UnixDomainSocketsConnectionFactory(udsEndPoint);
    var socketsHttpHandler = new SocketsHttpHandler
    {
        ConnectCallback = connectionFactory.ConnectAsync
    };

    return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
    {
        HttpHandler = socketsHttpHandler
    });
}

Kanály vytvořené pomocí předchozího kódu odesílají volání gRPC přes sokety domény Unix.