Pregunta Comunicación bidireccional asincrónica con Windows Named Pipes (.Net)


Tengo un servicio de Windows y una GUI que necesitan comunicarse entre ellos. Cualquiera puede enviar mensajes en cualquier momento.

Estoy buscando usar NamedPipes, pero parece que no puedes leer y escribir en la transmisión al mismo tiempo (o al menos no puedo encontrar ningún ejemplo que cubra este caso).

¿Es posible hacer este tipo de comunicación bidireccional a través de un solo NamedPipe? ¿O necesito abrir dos tuberías (una desde GUI-> servicio y otra desde servicio-> GUI)?


14
2018-05-08 04:42


origen


Respuestas:


Usando WCF puede usar dúplex con nombre de canalizaciones

// Create a contract that can be used as a callback
public interface IMyCallbackService
{
    [OperationContract(IsOneWay = true)]
    void NotifyClient();
}

// Define your service contract and specify the callback contract
[ServiceContract(CallbackContract = typeof(IMyCallbackService))]
public interface ISimpleService
{
    [OperationContract]
    string ProcessData();
}

Implementar el servicio

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class SimpleService : ISimpleService
{
    public string ProcessData()
    {
        // Get a handle to the call back channel
        var callback = OperationContext.Current.GetCallbackChannel<IMyCallbackService>();

        callback.NotifyClient();
        return DateTime.Now.ToString();
    }
}

Alojar el servicio

class Server
{
    static void Main(string[] args)
    {
        // Create a service host with an named pipe endpoint
        using (var host = new ServiceHost(typeof(SimpleService), new Uri("net.pipe://localhost")))
        {
            host.AddServiceEndpoint(typeof(ISimpleService), new NetNamedPipeBinding(), "SimpleService");
            host.Open();

            Console.WriteLine("Simple Service Running...");
            Console.ReadLine();

            host.Close();
        }
    }
}

Cree la aplicación cliente, en este ejemplo, la clase Cliente implementa el contrato de devolución de llamada.

class Client : IMyCallbackService
{
    static void Main(string[] args)
    {
        new Client().Run();
    }

    public void Run()
    {
        // Consume the service
        var factory = new DuplexChannelFactory<ISimpleService>(new InstanceContext(this), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/SimpleService"));
        var proxy = factory.CreateChannel();

        Console.WriteLine(proxy.ProcessData());
    }

    public void NotifyClient()
    {
        Console.WriteLine("Notification from Server");
    }
}

25
2018-05-08 05:20



El uso de un único punto para acumular mensajes (una sola tubería en este caso) también le obliga a manejar la dirección del mensaje (además de eso, debe usar un bloqueo de todo el sistema para la tubería).

Entonces usa 2 tubos con direcciones opuestas.

(Otra opción sería usar 2 colas MSMQ).


2
2018-05-08 05:17



Sus clases de flujo de canalización (servidor o cliente) deben construirse con una PipeDirection de InOut. Necesita un NamedPipeServerStream, probablemente en su servicio, que puede ser compartido por una cantidad arbitraria de objetos NamedPipeClientStream. Construya el NamedPipeServerStream con el nombre de la tubería y la dirección, y el NamedPipeClientStream con el nombre de la tubería, el nombre del servidor y PipeDirection, y debería estar listo para continuar.


1
2018-05-08 05:07