Comunicação entre processos com o gRPC e pipes nomeados
O .NET dá suporte à IPC (comunicação entre processos) usando gRPC. Para saber mais sobre como começar a usar o gRPC para se comunicar entre processos, confira Comunicação entre processos com gRPC.
Pipes nomeados são um transporte IPC com suporte em todas as versões do Windows. Os pipes nomeados integram-se bem à segurança do Windows para controlar o acesso do cliente ao pipe. Este artigo discute como configurar a comunicação gRPC em pipes nomeados.
Pré-requisitos
- .NET 8 ou posterior
- Windows
Configuração de Servidor
Os pipes nomeados são compatíveis com Kestrel, que é configurado em Program.cs
:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenNamedPipe("MyPipeName", listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
No exemplo anterior:
- Configura os pontos de extremidade do Kestrel em ConfigureKestrel.
- Chama
ListenNamedPipe
para escutar um pipe nomeado com o nome especificado. - Cria um ponto de extremidade de pipe nomeado que não está configurado para usar HTTPS. Para saber mais sobre como habilitar o HTTPS, confira Configuração do ponto de extremidade HTTPS de Kestrel.
Configuração do cliente
GrpcChannel
dá suporte à realização de chamadas gRPC em transportes personalizados. Quando um canal é criado, ele pode ser configurado com um SocketsHttpHandler que tem um ConnectCallback personalizado. O retorno de chamada permite que o cliente faça conexões por meio de transportes personalizados e envie solicitações HTTP por esse transporte.
Observação
Alguns recursos de conectividade de GrpcChannel
, como o balanceamento de carga do lado do cliente e o status do canal, não podem ser usados junto aos pipes nomeados.
Exemplo de fábrica de conexões de pipes nomeados:
public class NamedPipesConnectionFactory
{
private readonly string pipeName;
public NamedPipesConnectionFactory(string pipeName)
{
this.pipeName = pipeName;
}
public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
CancellationToken cancellationToken = default)
{
var clientStream = new NamedPipeClientStream(
serverName: ".",
pipeName: this.pipeName,
direction: PipeDirection.InOut,
options: PipeOptions.WriteThrough | PipeOptions.Asynchronous,
impersonationLevel: TokenImpersonationLevel.Anonymous);
try
{
await clientStream.ConnectAsync(cancellationToken).ConfigureAwait(false);
return clientStream;
}
catch
{
clientStream.Dispose();
throw;
}
}
}
Usando a fábrica de conexões personalizadas para criar um canal:
public static GrpcChannel CreateChannel()
{
var connectionFactory = new NamedPipesConnectionFactory("MyPipeName");
var socketsHttpHandler = new SocketsHttpHandler
{
ConnectCallback = connectionFactory.ConnectAsync
};
return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{
HttpHandler = socketsHttpHandler
});
}
Os canais criados usando o código anterior enviam chamadas gRPC por pipes nomeados.