I have an appliction that might be running multiple instances. I have a task that executes on all instances at the same time. I want to schedule an OS task to run a small app that sends message trough a named pipe, and I want to have all my instnces listenning on that pipe and doing their stuff. I tried WCF named pipes and got AddressAlreadyInUseException when I tried to run the second开发者_如何学编程 instnce.
Is it doable? Does it make sense? Am I aiming for the right solution? (Not that I don't need to send a reply from the appliction to the caller)
A typical approach is like this:
- A single 'load balancer' process has a well-known address and keeps listening on it.
- A 'worker' process starts and contacts the 'load balancer' process; this establishes a pipe between them.
- The 'load balancer' then routes requests and responses between 'workers' and the outside world, usually choosing the least busy 'worker' every time.
'Workers' need not listen on a pipe or a socket; you'd have to configure each of them differently and communicate this config to the 'load balancer'. With a listening 'load balancer', each 'worker' can be configured identically and only needs to know how to contact the 'load balancer'.
Windows Pipes (like real pipes which carry oil, water, or whatever) have just two ends, one end the server, the other a single client.
You can't have multiple clients "listening" on a single pipe, and each message sent down a pipe will be received by a single receiver.
You can have multiple servers all listening for pipe connections on the same pipe name, but the pipe name is just a rendezvous point, not a shared pipe instance. Each client connecting to the named pipe will be connected to a single server (which the client can't choose) by a single pipe instance. There is no reliable way to enumerate all listening servers. (And if you want to use WCF, the way the named pipe binding creates and publishes the actual pipe name means that, as you have discovered, only one service process at a time can listen on a particular service url).
Two possible approaches:
- Windows Mailslots support broadcasting in the way you require. Your worker processes would all create a mailslot using the same name, and monitor it for messages arriving. Your trigger app would send a message to the mailslot. The downside is that there is no .NET library class wrapping this functionality, so you would need to work directly with the Win32 API via P/Invoke.
- Turn your WCF service around and use the support for duplex messaging which the NetNamedPipeBinding provides. Your worker processes would be clients of a WCF service exposed either by the trigger application (if it is running all the time the worker processes are) or by a separate service acting as a broker (in this case it would expose a second service which the trigger app would use to initiate the notifications). The WCF service used by the worker processes would have Register and UnRegister operations which the worker processes would use to notify their starting and stopping. It would also have a callback contract which the trigger (or broker) app would use to send the task messages to the workers.
I would recommend the second approach as being less brittle (mailslot communication is entirely one way, so there is more scope for difficult to diagnose errors).
精彩评论