Compartir vía


Comunicación entre procesos con sockets de dominio gRPC y Unix

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulte la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulte la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulte la versión .NET 8 de este artículo.

Por James Newton-King

.NET admite la comunicación entre procesos (IPC) mediante gRPC. Para más información sobre cómo empezar a usar gRPC para comunicarse entre procesos, consulte Comunicación entre procesos con gRPC.

Los sockets de dominio Unix (UDS) son un transporte IPC ampliamente compatible que es más eficaz que TCP cuando el cliente y el servidor están en la misma máquina. En este artículo se describe cómo configurar la comunicación gRPC a través de UDS.

Requisitos previos

Configuración del servidor

Los sockets de dominio Unix son compatibles con Kestrel, que se configura en 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;
    });
});

Ejemplo anterior:

Configuración de cliente

GrpcChannel admite la realización de llamadas gRPC a través de transportes personalizados. Cuando se crea un canal, se puede configurar con un elemento SocketsHttpHandler que tenga un elemento ConnectCallback personalizado. La devolución de llamada permite al cliente realizar conexiones a través de transportes personalizados y, después, enviar solicitudes HTTP a través de ese transporte.

Nota:

Algunas características de conectividad de GrpcChannel, como el equilibrio de carga del lado cliente y el estado del canal, no se pueden usar junto con canalizaciones con sockets de dominio de Unix.

Ejemplo de fábrica de conexiones de sockets de dominio de Unix:

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

Uso del generador de conexiones personalizadas para crear un canal:

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

Los canales creados con el código anterior envían llamadas gRPC a través de sockets de dominio de Unix.