Проблема со связью в Mac OS - PullRequest
1 голос
/ 10 февраля 2012

Я занимаюсь разработкой приложения для MAC OS. Он состоит из 2 частей - элемента пользовательского интерфейса и демона (который должен работать непрерывно и должен быть перезапущен при уничтожении). В настоящее время я использую launchctl для перезапуска демона.

Но есть и другая проблема. Мне нужны две части моего приложения, чтобы общаться друг с другом. Для этого я использую распределенные объекты для того же самого (как дано здесь ). Однако это не работает, когда я запускаю демон с launchctl. Кто-нибудь может предложить какую-то альтернативу ???

Ответы [ 2 ]

2 голосов
/ 10 февраля 2012

Я использую NSDistributedNotifications, чтобы справиться с этим довольно хорошо в одном приложении, даже на 10.7.Вы должны сделать свое собственное рукопожатие, так как это может привести к потерям (то есть включить уведомление ack и отправить повторно в случае тайм-аута).Побочным эффектом этого подхода является то, что если запущено несколько клиентов (особенно при быстром переключении пользователей), все они получают уведомления.Это хорошо в частном случае этого приложения.Это также чрезвычайно просто реализовать.

Для другого приложения я использую два FIFO.Сервер пишет одному и читает другому.Клиент делает наоборот.Конечно, вы можете также использовать сетевой сокет для достижения того же.Я предпочитаю использовать FIFO, потому что вам не нужно иметь дело с блокировкой сетевого сокета.

Тем не менее, какую проблему вы видите при использовании распределенных объектов в launchd?Вы просто видите проблемы в 10.7 (которые изменили правила для контекста launchd)?

Используете ли вы launchd для отложенной загрузки демона при доступе к порту (это нормальный способ сделать это).Рассматривали ли вы использование агента запуска вместо launchdaemon?


РЕДАКТИРОВАТЬ:

Ах ... сервер начальной загрузки.Да.Вам нужно выполнить вещи в правильном контексте начальной загрузки, чтобы поговорить с ними.Контекст начальной загрузки для сеанса входа в систему связан с процессом windowserver.LaunchDaemons запускаются в другом контексте, поэтому они не могут напрямую взаимодействовать с сеансами входа в систему.Некоторое фоновое чтение:

Я не знаю, как получитьобрабатывает в правильном контексте без использования launchctl bsexec.Технически у Launchd есть API (используется launchctl), но он недостаточно хорошо документирован.Вы можете получить source с opensource.apple.com.

Даже если вы останетесь с NSDistributedObject, я постараюсь использовать что-то кроме службы начальной загрузки, если вы можете.Как я уже говорил, я склонен использовать другие инструменты и избегать NSDistributedObject.По моему мнению, по тем же причинам, что REST лучше, чем SOAP, простые протоколы обычно лучше, чем удаленные объекты.(YMMV) * ​​1038 *

1 голос
/ 10 февраля 2012

Если вы запускаете своего демона, используя sudo launchctl; Вы не должны использовать CFMessagePort и Distributed object для IPC. CFMessagePort и Distributed object реализуются с использованием службы начальной загрузки (многие подсистемы Mac OS X работают путем обмена сообщениями Маха с центральной службой. Чтобы такая подсистема работала, она должна быть в состоянии найти службу. Обычно это делается с помощью служба начальной загрузки Маха, которая позволяет процессу искать службу по имени). Если вы будете использовать DO or CFMessagePort; вы столкнетесь с проблемой пространства имен начальной загрузки. когда вы запустите свой демон с помощью sudo launchctl; ваша служба зарегистрирована в корневом пространстве имен начальной загрузки, поэтому ваши клиенты (работающие в режиме пользователя) не смогут использовать эти службы.
вы можете проверить сервис начальной загрузки, используя

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

Вы должны использовать UNIX Domain Sockets. Сокеты домена UNIX отчасти похожи на сокеты TCP / IP, за исключением того, что связь всегда локальна для компьютера. Вы получаете доступ к сокетам домена UNIX, используя тот же API сокетов BSD, который вы использовали бы для сокетов TCP / IP. Основным отличием является формат адреса. Для сокетов TCP / IP адресная структура (та, которую вы передаете для связывания, подключения и т. Д.) Имеет вид (struct sockaddr_in), которая содержит IP-адрес и номер порта. Для доменных сокетов UNIX структура адреса (struct sockaddr_un) содержит путь. Пример использования доменных сокетов UNIX в среде клиент / сервер см. В примере кода 'CFLocalServer' .
Взгляните на это Техническое примечание TN2083 Демоны и агенты
Daemon IPC Рекомендации
Основы Mach Bootstrap

У каждого пользователя есть отдельное пространство имен Маха. Вы не можете общаться между пространствами имен. Вам нужно будет использовать сокеты (NSSocketPort) вместо этого, которые не ограничены такими способами. [1]

...