2

I'm looking for a mechanism to use to create a simple many-to-many messaging system to allow Windows applications to communicate on a single machine but across sessions and desktops.

I have the following hard requirements:

  1. Must work across all Windows sessions on a single machine.
  2. Must work on Windows XP and later.
  3. No global configuration required.
  4. No central coordinator/broker/server.
  5. Must not require elevated privileges from the applications.

I do not require guaranteed delivery of messages.

I have looked at many, many options. This is my last-ditch request for ideas.

The following have been rejected for violating one or more of the above requirements:

ZeroMQ: In order to do many-to-many messaging a central broker is required.
Named pipes: Requires a central server to receive messages and forward them on.
Multicast sockets: Requires a properly configured network card with a valid IP address, i.e. a global configuration.
Shared Memory Queue: To create shared memory in the global namespace requires elevated privileges.

Multicast sockets so nearly works. What else can anyone suggest? I'd consider anything from pre-packaged libraries to bare-metal Windows API functionality.


(Edit 27 September) A bit more context:

By 'central coordinator/broker/server', I mean a separate process that must be running at the time that an application tries to send a message. The problem I see with this is that it is impossible to guarantee that this process really will be running when it is needed. Typically a Windows service would be used, but there is no way to guarantee that a particular service will always be started before any user has logged in, or to guarantee that it has not been stopped for some reason. Run on demand introduces a delay when the first message is sent while the service starts, and raises issues with privileges.

Multicast sockets nearly worked because it manages to avoid completely the need for a central coordinator process and does not require elevated privileges from the applications sending or receiving multicast packets. But you have to have a configured IP address - you can't do multicast on the loopback interface (even though multicast with TTL=0 on a configured NIC behaves as one would expect of loopback multicast) - and that is the deal-breaker.

Ian Goldby
  • 5,609
  • 1
  • 45
  • 81

4 Answers4

1

Maybe I am completely misunderstanding the problem, especially the "no central broker", but have you considered something based on tuple spaces?

-- After the comments exchange, please consider the following as my "definitive" answer, then:

Use a file-based solution, and host the directory tree on a Ramdisk to insure good performance.

I'd also suggest to have a look at the following StackOverflow discussion (even if it's Java based) for possible pointers to how to manage locking and transactions on the filesystem.

This one (.NET based) may be of help, too.

Community
  • 1
  • 1
p.marino
  • 6,244
  • 3
  • 25
  • 36
  • I could implement that using shared memory. But to create shared memory in the global namespace on Windows Vista and later you need elevated privileges, which makes it a no go for my particular application. In any case, I'm looking for a lower-level concept - notionally an implementation for something like tuple spaces that does not violate my requirements listed above. – Ian Goldby Sep 26 '11 at 13:14
  • What about a filesystem-based solution then? I.e. implement your tuple space as a set of directories/files? Performance problems? – p.marino Sep 27 '11 at 08:26
  • It's a possibility, but seems klunky, plus as you said, poor performance. – Ian Goldby Sep 27 '11 at 10:57
  • it looks as the best bet due to your current requirements. In order to mitigate the performance problems, and considering this will work (if I am correct) as a temporary blackboard for message passing, I'd investigate a Ram Disk solution. These still exists, apparently, here is one for Windows 7, Windows Vista, XP, Server, for example: http://memory.dataram.com/products-and-services/software/ramdisk – p.marino Sep 27 '11 at 12:40
  • The RAM disk is a really neat idea - shared memory without the privileges problem. One could use LockFileEx() in order to synchronise access to the file without requiring any other named synchronisation objects. – Ian Goldby Sep 29 '11 at 14:27
0

How about UDP broadcasting?

Jonas Elfström
  • 30,834
  • 6
  • 70
  • 106
  • http://codeidol.com/csharp/csharp-network/IP-Multicasting/What-Is-Broadcasting/ - decent example. – Jonas Elfström Sep 26 '11 at 12:55
  • That's my 'Multicast Sockets' option. But you cannot broadcast or multicast to the loopback address. A configured IP address is required, which violates constraint 3. Not all machines on which this software is to be installed will have a network interface card with a configured IP address. – Ian Goldby Sep 26 '11 at 12:58
  • If some of the machines don't even have a network interface I find it strange that you stated that multicast nearly worked. Are those machines run from the console? Why no network interface? Sounds strange. – Jonas Elfström Sep 26 '11 at 17:08
  • You misread the question. I'm looking for a mechanism that works **on a single machine**. It is not for communication across a network. – Ian Goldby Sep 27 '11 at 07:21
  • Please describe the machine/software and the scenario in more detail. – Jonas Elfström Sep 27 '11 at 08:59
  • I only mentioned Terminal Services because it is a scenario where not all of the applications will be running in the same Windows Session. But some of the software is implemented as services, which (on Vista and later) never run in the same session as the GUI applications anyway. And Fast User Switching must also work properly. Don't get hung up on the fact that Terminal Services requires a configured TCP/IP network interface. In fact, forget Terminal Services and concentrate on Session isolation and Fast User Switching. – Ian Goldby Sep 27 '11 at 10:54
0

Couldn't you use a localhost socket ?

/Tony

SpagnumMoss
  • 104
  • 6
  • A datagram sent to localhost will be received only by one listener. The sender would have to maintain a list of listeners, effectively becoming the coordinating process and violating requirement 4 above. – Ian Goldby Sep 26 '11 at 13:09
  • I just checked, and if you sendto() INADDR_LOOPBACK (i.e. not multicasting) then only the first application to start listening on the socket gets the message. I need the listeners to get a copy each. – Ian Goldby Sep 26 '11 at 13:21
0

In the end I decided that one of the hard requirements had to go, as the problem could not be solved in any reasonable way as originally stated.

My final solution is a Windows service running a named pipe server. Any application or service can connect to an instance of the pipe and send messages. Any message received by the server is echoed to all pipe instances.

I really liked p.marino's answer, but in the end it looked like a lot of complexity for what is really a very basic piece of functionality.

The other possibility that appealed to me, though again it fell on the complexity hurdle, was to write a kernel driver to manage the multicasting. There would have been several mechanisms possible in this case, but the overhead of writing a bug-free kernel driver was just too high.

Ian Goldby
  • 5,609
  • 1
  • 45
  • 81