Partager via


Communication interprocessus avec des sockets de domaine gRPC et Unix

Par James Newton-King

.NET prend en charge la communication entre processus (IPC) à l’aide de gRPC. Pour plus d’informations sur la prise en main de l’utilisation de gRPC pour communiquer entre processus, consultez Communication entre processus avec gRPC.

Les sockets de domaine Unix (UDS) sont un transport IPC largement pris en charge qui est plus efficace que TCP lorsque le client et le serveur se trouvent sur la même machine. Cet article explique comment configurer la communication gRPC sur UDS.

Prérequis

Configurer le serveur

Les sockets de domaine Unix sont pris en charge par Kestrel, qui est configuré dans 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;
    });
});

L’exemple précédent :

Configuration de client

GrpcChannel prend en charge les appels gRPC sur des transports personnalisés. Lorsqu’un canal est créé, il peut être configuré avec un SocketsHttpHandler qui a un ConnectCallback personnalisé. Le rappel permet au client d’établir des connexions via des transports personnalisés, puis d’envoyer des requêtes HTTP sur ce transport.

Remarque

Certaines fonctionnalités de connectivité de GrpcChannel, telles que l’équilibrage de charge côté client et l’état du canal, ne peuvent pas être utilisées avec des sockets de domaine Unix.

Exemple de fabrique de connexions de sockets de domaine 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;
        }
    }
}

Utilisation de la fabrique de connexion personnalisée pour créer 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
    });
}

Les canaux créés à l’aide du code précédent envoient des appels gRPC sur des sockets de domaine Unix.