Question

I need to notify 1-many clients to perform a task (reload). The server may or may not be running at any given point in time. (For this reason, I have had some difficulty defining who is the client and who is the server.)

At any given time, the server may start running. When the server closes itself, it will notify all clients to perform their task.

I tried using a NamedPipeServerStream and running multiple instances on the "clients" (remember the relationship is odd so bear with me). Unfortunetly, I can only create one Pipe server for any given server name. So this did not work. I could have the clients continously check for a server, but if I'm going to start polling then I might as well poll the DB directly.

My situation is roughly like an observer pattern. I do not need to dynamically subscribe/unsubscribe. I do want the server to push a notifcation to all running clients to perform a task.

How can I achieve this? Please keep in mind I have to do this with IPC. The server/clients are running under different processes and always on the same machine.

Was it helpful?

Solution

To solve the polling problem you can create a named ManualResetEvent that the client processes will listen to. The clients will spin up a thread then wait on the event, when the server starts it will signal the event and let all of the clients start their listening code which can open a named pipe like you do currently. Look at the EventWaitHandle.GetAccessControl MSDN page to see a example of how to make a named ManualResetEvent.

For your I can only create one Pipe server for any given server name. issue, if there are multiple servers running how are the clients supposed to know which server to connect to? You said it was a 1 server to * client relationship. If you are going to run multiple servers you will need a way to tell the client which server it should listen to.

OTHER TIPS

Because you specified that the processes are all guaranteed to be on the same machine, I would probably look at using a windows named event. Your client(s) and server can call OpenEvent, if the event hasn't been created, call CreateEvent. This will give you some control (using pulseevent, set/reset, etc) over how many clients are released per event, and also allow you to open a client without the server already existing.

As Scott suggests, to easily do this in c#, use a .net named EventWaitHandle, by calling a constructor that takes a string (such as this one). Which will create the system-wide synchronization object for you. That particular constructor will also tell you if you were the first to ask for the event (you created it), or it was already in existence.

Using named shared memory would be one way to accomplish a one-to-many communication. The server can create the shared memory, and one or more of the clients can open it and read it. An example (in C) is shown here. In addition, a .NET example is shown here.

The shared memory will exist as long as at least one process has an open handle to it. From the OP, this sounds as if it would be a useful feature because the memory could continue its existence even after the server process was closed (as long as at least one client still had it open). The .NET example also shows how to persist the information, which would be useful if it has to outlive the processes.

Depending on the timing needed, clients could either periodically read the memory for the necessary information. Or if a more time-critical situation exists, you could use a named semaphore to signal clients to perform necessary operations. With a semaphore as the synchronization object, you can signal multiple clients by setting the release count to a value greater than 1.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top