Question

I am developing an application on MAC OS . It has 2 parts -- a UI element and a daemon (which needs to run continuously and must restart on being killed). Currently I am using launchctl to restart the daemon.

But there is another issue. I need the 2 parts of my application to communicate with each other . For this I am using distibuted objects for the same (as given here) . However this does not work when I launch the daemon with launchctl. Can anyone suggest some alternative???

Was it helpful?

Solution

I use NSDistributedNotifications to handle this pretty well in one app, even on 10.7. You have to do your own handshaking since this can be lossy (i.e. include an ack notification and resend in case of timeouts). A side effect of this approach is that if there are multiple clients running (particularly under fast user switching), all of them receive the notifications. That's good in the particular case of this app. It's also extremely simple to implement.

For another app, I use two FIFOs. The server writes to one and reads from the other. The client does the opposite. You can of course also use a network socket to achieve the same thing. I tend to prefer FIFOs because you don't have to do deal with locking down a network socket.

That said, what problem are you seeing using distributed objects under launchd? Are you just seeing problems on 10.7 (which changed the rules around the launchd context)?

Are you using launchd to lazy-load the daemon when the port is accessed (this is the normal way to do it). Have you considered using a launchagent instead of a launchdaemon?


EDIT:

Ah... the bootstrap server. Yes. You need to execute things in the correct bootstrap context in order to talk to them. The bootstrap context for the login session is rooted to the windowserver process. LaunchDaemons run in a different context, so they can't directly communicate with the login sessions. Some background reading:

I am not aware of anyway to get processes into the correct context without using launchctl bsexec. Launchd technically has an API (launchctl uses it), but it is not well documented. You can pull the source from opensource.apple.com.

Even if you stay with NSDistributedObject, I would try to use something other than the bootstrap service if you can. As I mentioned, I tend to use other tools and avoid NSDistributedObject. In my opinion, for the same reasons that REST is better than SOAP, simple protocols are usually better than remote objects. (YMMV)

OTHER TIPS

If you are launching your daemon using sudo launchctl; You should not use CFMessagePort and Distributed object for IPC. CFMessagePort and Distributed object are implemented using the bootstrap service(Many Mac OS X subsystems work by exchanging Mach messages with a central service. For such a subsystem to work, it must be able to find the service. This is typically done using the Mach bootstrap service, which allows a process to look up a service by name). If you will use DO or CFMessagePort; you will run into bootstrap namespace problem. when you will launch your daemon using sudo launchctl ; your service is register in root bootstrap namespace so your clients(running in user mode) will not able to use that services.
you can check bootstrap service using

$ launchctl bslist
$ sudo launchctl bslist // If you are using sudo lunchctl

You should use UNIX Domain Sockets. UNIX domain sockets are somewhat like TCP/IP sockets, except that the communication is always local to the computer. You access UNIX domain sockets using the same BSD sockets API that you'd use for TCP/IP sockets. The primary difference is the address format. For TCP/IP sockets, the address structure (that which you pass to bind, connect, and so on) is (struct sockaddr_in), which contains an IP address and port number. For UNIX domain sockets, the address structure is (struct sockaddr_un), which contains a path.For an example of using UNIX domain sockets in a client/server environment, see Sample Code 'CFLocalServer'.
Take a look at this Technical Note TN2083 Daemons and Agents
Daemon IPC Recommendations
Mach Bootstrap Basics

Each user has a separate Mach namespace .You cannot communicate between namespaces.  You'll need to use sockets (NSSocketPort) instead, which are not limited in such ways.[1]

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