我正在开发MAC OS上的应用程序。它有两个部分 - 一个UI元素和一个守护进程(需要连续运行,并且必须在被杀死时重新启动)。目前我正在使用launchctl来重启守护进程。
但还有另一个问题。我需要我的应用程序的两个部分相互通信。为此,我使用相同的distibuted对象(给定here)。但是,当我使用launchctl启动守护程序时,这不起作用。谁能建议一些替代方案???
答案 0 :(得分:2)
我使用NSDistributedNotifications
在一个应用程序中处理这个问题,即使在10.7上也是如此。您必须进行自己的握手,因为这可能是有损的(即包括ack
通知并在超时的情况下重新发送)。这种方法的副作用是,如果有多个客户端正在运行(特别是在快速用户切换下),则所有客户端都会收到通知。在这个应用程序的特定情况下这是好的。它的实施也非常简单。
对于另一个应用程序,我使用两个FIFO。服务器写入一个并从另一个读取。客户反其道而行之。您当然也可以使用网络套接字来实现相同的功能。我倾向于选择FIFO,因为你不需要处理锁定网络套接字。
那就是说,你在launchd下看到使用分布式对象有什么问题?您是否只是在10.7上看到问题(这改变了启动上下文的规则)?
您是否在访问端口时使用launchd来延迟加载守护进程(这是正常的方法)。您是否考虑使用启动而不是启动守护程序?
编辑:
啊......引导服务器。是。您需要在正确的引导上下文中执行操作才能与它们进行通信。登录会话的引导上下文植根于windowserver
进程。 LaunchDaemons在不同的上下文中运行,因此无法直接与登录会话进行通信。一些背景阅读:
我不知道在不使用launchctl bsexec
的情况下将流程置于正确的上下文中。 Launchd在技术上有一个API(launchctl使用它),但它没有很好的文档记录。您可以从opensource.apple.com中提取source。
即使你留在NSDistributedObject
,如果可以,我会尝试使用除引导服务之外的其他东西。正如我所提到的,我倾向于使用其他工具并避免使用NSDistributedObject
。在我看来,由于REST优于SOAP的原因相同,简单协议通常比远程对象更好。 (YMMV)
答案 1 :(得分:1)
如果您使用sudo launchctl
启动守护程序;您不应该将CFMessagePort
和Distributed object
用于IPC。 CFMessagePort
和Distributed object
是使用引导服务实现的(许多Mac OS X子系统通过与中央服务交换Mach消息来工作。要使这样的子系统工作,它必须能够找到服务。通常使用Mach引导服务完成,该服务允许进程按名称查找服务)。
如果您将使用DO or CFMessagePort
;你会遇到bootstrap命名空间问题。
当你使用sudo launchctl启动你的守护进程;您的服务在root bootstrap命名空间中注册,因此您的客户端(以用户模式运行)将无法使用该服务
你可以使用
$ launchctl bslist
$ sudo launchctl bslist // If you are using sudo lunchctl
您应该使用UNIX Domain Sockets
。 UNIX域套接字有点像TCP / IP套接字,但通信始终是计算机的本地通信。您使用与TCP / IP套接字相同的BSD套接字API访问UNIX域套接字。主要区别在于地址格式。对于TCP / IP套接字,地址结构(您传递给绑定,连接等的地址)是(struct sockaddr_in),其中包含IP地址和端口号。对于UNIX域套接字,地址结构为(struct sockaddr_un),其中包含路径。有关在客户端/服务器环境中使用UNIX域套接字的示例,请参阅示例代码'CFLocalServer'。
看一下这个Technical Note TN2083 Daemons and Agents
Daemon IPC Recommendations
Mach Bootstrap Basics
每个用户都有一个单独的Mach命名空间。您无法进行通信 名称空间之间。你需要使用套接字(NSSocketPort) 相反,它不受这种方式的限制。[1]