使用 XPC 创建守护进程/UI 连接

Posted

技术标签:

【中文标题】使用 XPC 创建守护进程/UI 连接【英文标题】:Creating Daemon / UI connection using XPC 【发布时间】:2017-12-28 07:12:07 【问题描述】:

我的平台包含基于混合 c++/objective-c 代码的系统范围守护程序,由 launchd 根据位于 /Library/LaunchDaemons/ 的正确配置的 plist 文件操作。

另一方面,它包含使用故事板构建的基于 UI 的应用程序,该应用程序从后台运行并定义为 LaunchAgent(这意味着它也由 launchd 使用 /Library/LaunchAgents/ 中的 plist 文件操作)

现在我希望在它们之间建立单向连接,以便守护程序可以发送消息以供 UI 应用程序显示。消息可以包含字符串/数字或任何其他可显示的数据。

我检查了使用 XPC 连接的选项并将NSXPCConnection 添加到我的守护程序中,该守护程序与使用NSXPCListener 在 UI 端实现的服务器共享一个专用协议。

我很乐意收到关于我的设计的评论和建议,尤其是在以下方面

1. Should I implement the UI as launchAgent 
(I need to support multi-users, meaning that the daemon can send
different messages to each UI instance per user) 

.

2. should I consider using dedicated `XPC service`. 
Seems like Xcode has option to create XPC service, 
but I don't know how should I "attach" the UI code inside ... 

.

3. is it possible to have XPC client which runs objective-c 
code while the XPC listener will run on swift code ? 

谢谢

【问题讨论】:

【参考方案1】:
    将 UI 应用程序实现为常规应用程序或启动代理并不重要。选择更适合的。 您是否正在考虑拥有一个 UI 应用程序和一个 XPC 服务?这应该可行。 它适用于 Swift、Objective-C 和混合语言项目。

现在我希望在它们之间建立单向连接,以便守护程序可以发送消息以供 UI 应用程序显示。

它对我不起作用。根进程无法初始化与用户进程的通信。但反之亦然:如果连接是由 UI 发起的(你在 UI 中实例化 NSXPCConnection,在 Daemon 中实例化一个监听器)。

【讨论】:

谢谢!根据您的建议,我已经更改了 XPC 连接的过程,并且可以正常工作!但是,出于性能原因,有什么方法可以将消息从服​​务器发起到客户端,因为在我的项目中,守护进程负责发起所有消息,并且我希望避免从客户端发送持续的 keep-alives (现在是 UI) 很高兴它有帮助!不幸的是,我没有找到任何文档或解决此问题的方法。看起来,在使用 Mach Ports 时也会重现给定的行为(用户进程可以与 root 对话,但不能反过来)。【参考方案2】:

我认为你应该阅读 Apple 的守护进程和服务编程指南:https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/Introduction.html#//apple_ref/doc/uid/10000172i-SW1-SW1

    UI 可能应该作为与您的守护程序通信的常规应用程序来完成。

    我认为 XPC 服务不能满足您的需求,因为您说您需要支持多个用户。

XPC 服务是私有的,仅对包含它的主应用程序可用。

    是的。您可能会使用 NSXPCConnection 类,它位于 Foundation 中,它与 Swift 和 Objective-C 兼容。

【讨论】:

以上是关于使用 XPC 创建守护进程/UI 连接的主要内容,如果未能解决你的问题,请参考以下文章

通过 XPC 与应用程序通信并启动以 root 身份运行的守护程序

从命令行守护程​​序使用 MLMediaLibrary 时出现 XPC 错误

创建Android守护进程(底层服务)

Linux守护进程详解

linux守护进程配置文件

登录ubuntu之前如何在python守护进程中使用DBUS