Communicatie tussen processen met gRPC- en Unix-domeinsockets

Opmerking

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 10-versie van dit artikel voor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie het .NET- en .NET Core-ondersteuningsbeleid voor meer informatie. Zie de .NET 10-versie van dit artikel voor de huidige release.

Door James Newton-King

.NET ondersteunt communicatie tussen processen (IPC) met behulp van gRPC. Zie Interprocescommunicatie met gRPC voor meer informatie over het gebruik van gRPC om te communiceren tussen processen.

Unix-domeinsockets (UDS) is een algemeen ondersteund IPC-transport dat efficiƫnter is dan TCP wanneer de client en server zich op dezelfde computer bevinden. In dit artikel wordt beschreven hoe u gRPC-communicatie configureert via UDS.

Vereiste voorwaarden

Serverconfiguratie

Unix-domeinsockets worden ondersteund door Kestrel, die is geconfigureerd in 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;
    });
});

Het voorgaande voorbeeld:

  • Kestrel configureert de eindpunten in ConfigureKestrel.
  • Oproepen ListenUnixSocket om naar een UDS te luisteren met het opgegeven pad.
  • Hiermee maakt u een UDS-eindpunt dat niet is geconfigureerd voor het gebruik van HTTPS. Zie https-eindpuntconfiguratie voor meer informatie over het inschakelen van HTTPSKestrel.

Clientconfiguratie

GrpcChannel ondersteunt het maken van gRPC-aanroepen via aangepaste transporten. Wanneer een kanaal wordt gemaakt, kan het worden geconfigureerd met een SocketsHttpHandler dat een aangepaste ConnectCallback heeft. Met de callback kan de client verbindingen maken via aangepaste transporten en vervolgens HTTP-aanvragen verzenden via dat transport.

Opmerking

Sommige connectiviteitsfuncties, GrpcChannelzoals taakverdeling aan de clientzijde en kanaalstatus, kunnen niet samen met Unix-domeinsockets worden gebruikt.

Voorbeeld van een Unix-domeinsocket-connectiefabriek:

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

Gebruik de custom connection factory om een kanaal te maken:

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

Kanalen die zijn gemaakt met behulp van de voorgaande code verzenden gRPC-aanroepen via Unix-domeinsockets.