2012-02-10 28 views
1

我正在MAC OS上開發應用程序。它有2個部分 - 一個UI元素和一個守護進程(它需要連續運行,並且必須在被終止時重新啓動)。目前我正在使用launchctl來重新啓動守護程序。Mac OS中的通信問題

但還有另一個問題。我需要我的應用程序的兩部分相互溝通。爲此我使用相同的分佈對象(如給出here)。但是,當我使用launchctl啓動守護進程時,這不起作用。任何人都可以提出一些替代?

回答

2

我使用NSDistributedNotifications在一個應用程序中處理這個問題,甚至在10.7上。您必須自己動手握手,因爲這可能是有損的(即包含ack通知並在超時情況下重新發送)。這種方法的一個副作用是,如果有多個客戶端正在運行(特別是在快速用戶切換下),他們都會收到通知。這在這個應用程序的特殊情況下很好。實施起來也非常簡單。

對於另一個應用程序,我使用了兩個FIFO。服務器寫入一個並從另一個讀取。客戶做的是相反的。您當然也可以使用網絡套接字來實現相同的功能。我傾向於選擇FIFO,因爲您不必處理鎖定網絡套接字。

這就是說,你看到使用launchd下的分佈式對象有什麼問題?你剛纔看到10.7的問題(它改變了啓動環境的規則)?

您是否在使用launchd在端口被訪問時延遲加載守護程序(這是執行此操作的常用方法)。你有沒有考慮使用launchchagent而不是launchdaemon?


編輯:

啊......引導服務器。是。你需要在正確的引導環境中執行,以便與他們交談。登錄會話的引導環境根源於windowserver進程。 LaunchDaemons運行在不同的上下文中,因此它們無法直接與登錄會話進行通信。一些背景閱讀:

我不知道反正拿到進程進入正確的上下文,而無需使用launchctl bsexec。技術上推出了一個API(launchctl使用它),但它沒有很好的文檔。您可以從opensource.apple.com取得source

即使你留在NSDistributedObject,我會嘗試使用除引導服務以外的東西,如果可以的話。正如我所提到的,我傾向於使用其他工具並避免NSDistributedObject。在我看來,出於同樣的原因,REST比SOAP更好,簡單的協議通常比遠程對象更好。 (YMMV)

+0

對於分佈式對象,我在[NSMachBootstrapServer sharedInstance]上註冊了我的連接。但是這個函數爲我的應用程序和守護進程返回的對象是不同的。直到我只使用sudo啓動守護進程時,它工作正常,但它停止使用sudo launchctl。你能提出建議嗎? – 2012-02-17 11:48:09

1

如果您使用sudo launchctl啓動守護進程, IPC不應使用CFMessagePortDistributed objectCFMessagePortDistributed object是使用引導程序服務實現的(許多Mac OS X子系統通過與中央服務交換Mach消息來工作。要使這樣的子系統正常工作,它必須能夠找到服務。這通常使用Mach引導程序服務完成,它允許進程按名稱查找服務)。 如果您將使用DO or CFMessagePort;你會遇到bootstrap命名空間問題。 當你將啓動你的守護進程使用sudo launchctl;您的服務在根引導程序名稱空間中註冊,因此您的客戶端(以用戶模式運行)將無法使用該服務。
您可以使用

$ 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

每個用戶都有一個單獨的命名空間馬赫。你不能命名空間之間溝通 看看。您需要使用套接字(NSSocketPort) ,而不是以這種方式進行限制。 [1]