Kommunikation mellan processer med gRPC- och Unix-domänuttag

Anmärkning

Det här är inte den senaste versionen av den här artikeln. Den aktuella versionen finns i .NET 10-versionen av den här artikeln.

Varning

Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i supportpolicyn för .NET och .NET Core. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln .

Av James Newton-King

.NET stöder kommunikation mellan processer (IPC) med hjälp av gRPC. Mer information om hur du kommer igång med att använda gRPC för att kommunicera mellan processer finns i Kommunikation mellan processer med gRPC.

Unix-domän sockets (UDS) är en IPC-transport med brett stöd som är effektivare än TCP när klienten och servern finns på samma dator. I den här artikeln beskrivs hur du konfigurerar gRPC-kommunikation via UDS.

Förutsättningar

Serverkonfiguration

Unix-domänsocketer stöds av Kestrel, som konfigureras i 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;
    });
});

Föregående exempel:

Klientkonfiguration

GrpcChannel stöder gRPC-anrop via anpassade transporter. När en kanal skapas kan den konfigureras med en SocketsHttpHandler som har en anpassad ConnectCallback. Återanropet gör att klienten kan upprätta anslutningar via anpassade transporter och sedan skicka HTTP-begäranden via den transporten.

Anmärkning

Vissa anslutningsfunktioner hos GrpcChannel, till exempel belastningsutjämning på klientsidan och kanalstatus, kan inte användas tillsammans med Unix-domänsocket.

Exempel på anslutningsfabrik för Unix-domänsocketer:

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

Använd den anpassade anslutningsfabriken för att skapa en kanal:

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

Kanaler som skapats med hjälp av föregående kod skickar gRPC-anrop via Unix-domänsocketer.