Share via


使用 gRPC 與 Unix 網域通訊端進行處理序間通訊

作者:James Newton-King

.NET 支援使用 gRPC 進行處理序間通訊 (IPC)。 如需開始使用 gRPC 在處理序之間通訊的詳細資訊,請參閱使用 gRPC 進行處理序間通訊

Unix 網域通訊端 (UDS) 是廣受支援的 IPC 傳輸,若用戶端和伺服器位於同一部電腦上,則會比 TCP 更有效率。 本文討論如何透過 UDS 設定 gRPC 通訊。

必要條件

伺服器組態

Kestrel 支援 Unix 網域通訊端,而前者設定於 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;
    });
});

上述範例:

用戶端組態

GrpcChannel 支援透過自訂傳輸進行 gRPC 呼叫。 建立通道後,可以使用具有自訂 ConnectCallbackSocketsHttpHandler 加以設定。 回呼可讓用戶端透過自訂傳輸進行連線,然後透過該傳輸傳送 HTTP 要求。

注意

的某些 GrpcChannel連線功能,例如用戶端負載平衡和通道狀態,無法與 Unix 網域套接字搭配使用。

Unix 網域通訊端連線 Factory 範例:

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

使用自訂連線 Factory 建立通道:

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

使用上述程式碼建立的通道會透過 Unix 網域通訊端傳送 gRPC 呼叫。