Лучший способ сделать межпроцессное взаимодействие в Mac OS X

Я смотрю на создание приложения Какао на Mac с внутренним процессом-демоном (возможно, на самом деле это просто приложение Coco без головы), а также с 0 или более "клиентскими" приложениями, работающими локально (хотя, если бы я мог, хотел бы также поддерживать удаленные клиенты; удаленные клиенты будут когда-либо только другими компьютерами Mac или iPhone OS).

Передаваемые данные будут довольно тривиальными, в основном это просто текст и команды (которые, я думаю, в любом случае можно представить в виде текста) и, возможно, случайный небольшой файл (возможно, изображение).

Я рассмотрел несколько способов сделать это, но я не уверен, что "лучше" для поставленной задачи. Вещи, которые я рассмотрел:

  • Чтение и запись в файл (… да), очень простой, но не очень масштабируемый.
  • Чистые сокеты (у меня нет опыта работы с сокетами, но я думаю, что могу использовать их для отправки данных локально и по сети. Хотя это кажется громоздким, если делать все в Какао
  • Распределенные объекты: кажется довольно не элегантным для такой задачи, как эта
  • NSConnection: Я не могу понять, что вообще делает этот класс, но я читал об этом в некоторых результатах поиска IPC

Я уверен, что есть вещи, которые мне не хватает, но я был удивлен, обнаружив нехватку ресурсов на эту тему.

3 ответа

Решение

В настоящее время я смотрю на те же вопросы. Для меня возможность добавления клиентов Windows позже усложняет ситуацию; в вашем случае ответ кажется более простым.

О вариантах, которые вы рассмотрели:

  1. Управляющие файлы. Хотя существует возможность обмена данными через управляющие файлы, вы должны помнить, что файлы должны передаваться через сетевую файловую систему между задействованными компьютерами. Таким образом, сетевая файловая система служит абстракцией реальной сетевой инфраструктуры, но не обеспечивает полной мощности и гибкости, которые обычно имеет сеть. Реализация: на практике вам потребуется как минимум два файла для каждой пары клиент / сервер: файл, который сервер использует для отправки запроса клиенту (-ам), и файл для ответов. Если каждый процесс может взаимодействовать в обоих направлениях, вам необходимо продублировать это. Кроме того, как клиент (ы), так и сервер (ы) работают по принципу "извлечения", т. Е. Им необходимо часто пересматривать контрольные файлы и проверять, было ли доставлено что-то новое.

    Преимущество этого решения в том, что оно сводит к минимуму необходимость изучения новых методов. Большой недостаток в том, что он предъявляет огромные требования к логике программы; Вы должны позаботиться о многих вещах (Будут ли файлы записаны в виде одного куска или может случиться так, что какая-либо сторона получит несогласованные файлы? Как часто следует проводить проверки? Нужно ли беспокоиться о файловой системе, например, кэширование и т. д. Могу ли я добавить шифрование позже, не разбираясь с вещами вне моего программного кода?...)

    Если бы переносимость была проблемой (что, насколько я понял из вашего вопроса, не так), то это решение было бы легко перенести на разные системы и даже на разные языки программирования. Тем не менее, я не знаю никаких сетевых файлов для iPhone OS, но я не знаком с этим.

  2. Сокеты: интерфейс программирования определенно отличается; в зависимости от вашего опыта программирования сокетов, это может означать, что у вас больше работы, сначала изучая его, а потом отлаживая. Реализация: на практике вам потребуется аналогичная логика, как и раньше, т. Е. Клиент (ы) и сервер (ы), взаимодействующие через сеть. Несомненным плюсом этого подхода является то, что процессы могут работать в режиме "push", т. Е. Они могут прослушивать сокет до тех пор, пока не прибудет сообщение, что лучше регулярной проверки управляющих файлов. Повреждение сети и несоответствия также не являются вашей заботой. Кроме того, вы (можете) лучше контролировать способ установления соединений, чем полагаться на вещи, находящиеся вне контроля вашей программы (опять же, это важно, если вы решите добавить шифрование позже).

    Преимущество состоит в том, что многие вещи снимаются с ваших плеч, что мешает реализации в 1. Недостатком является то, что вам все еще нужно существенно изменить логику программы, чтобы убедиться, что вы отправляете и получаете правильную информацию (типы файлов так далее.).

    По моему опыту переносимость (т. Е. Простота перехода на другие системы и даже языки программирования) очень хороша, поскольку работает все, что даже удаленно совместимо с POSIX.

    [РЕДАКТИРОВАТЬ: В частности, как только вы сообщаете двоичные числа, проблема с бесконечностью становится проблемой, и вы должны решить эту проблему вручную - это частый (!) Особый случай проблемы "правильной информации", о которой я упоминал выше. Он будет кусать вас, например, когда у вас PowerPC разговаривает с Intel Mac. Этот частный случай исчезает с решением 3.+4. вместе будут все другие вопросы "правильной информации".]

  3. +4. Распределенные объекты: NSProxy Кластер классов используется для реализации распределенных объектов. NSConnection отвечает за настройку удаленных подключений в качестве предварительного условия для отправки информации, поэтому, как только вы поймете, как использовать эту систему, вы также поймете распределенные объекты.;^)

    Идея состоит в том, что логику вашей высокоуровневой программы не нужно менять (т. Е. Ваши объекты обмениваются сообщениями и получают результаты, а сообщения вместе с типами возврата идентичны тем, к которым вы привыкли в локальной реализации), не имея беспокоиться об особенностях сетевой инфраструктуры. Ну, по крайней мере, в теории. Реализация: я тоже сейчас работаю над этим, поэтому мое понимание все еще ограничено. Насколько я понимаю, вам нужно настроить определенную структуру, т. Е. Вам все еще нужно решить, какие процессы (локальные и / или удаленные) могут получать какие сообщения; Это то, что NSConnection делает. На этом этапе вы неявно определяете архитектуру клиент / сервер, но вам не нужно беспокоиться о проблемах, упомянутых в 2.

    На сервере проекта Gnustep есть введение с двумя явными примерами; он показывает, как работает технология, и является хорошей отправной точкой для экспериментов: http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_7.html

    К сожалению, недостатками являются полная потеря совместимости (хотя вы все равно хорошо справитесь с настройками Mac и iPhone/iPad, которые вы упомянули) с другими системами и потеря переносимости на другие языки. Gnustep с Objective-C в лучшем случае совместим с кодом, но между Gnustep и Cocoa нет возможности связаться, см. Мое изменение к вопросу № 2 здесь: CORBA в Mac OS X (Какао)

    [РЕДАКТИРОВАТЬ: Я только что наткнулся на другую информацию, которую я не знал. Пока я проверял это NSProxy доступно на iPhone, я не проверял, есть ли другие части механизма распределенных объектов. По этой ссылке: http://www.cocoabuilder.com/archive/cocoa/224358-big-picture-relationships-between-nsconnection-nsinputstream-nsoutputstream-etc.html (поищите на странице фразу "iPhone OS") они не. Это исключило бы это решение, если вы хотите использовать iPhone/iPad в данный момент.]

Итак, в заключение следует отметить, что существует компромисс между усилиями по изучению (и внедрению и отладке) новых технологий, с одной стороны, и кодированию низкоуровневой логики связи, с другой. В то время как подход с распределенными объектами берет на себя большую нагрузку на ваши плечи и влечет за собой наименьшие изменения в логике программы, он труднее всего изучать, а также (к сожалению) наименее переносим.

Отказ от ответственности: Распределенные объекты недоступны на iPhone.


Почему вы находите распределенные объекты не элегантными? Они звучат как хороший матч здесь:

  • прозрачное распределение основных типов и классов Objective C
  • на самом деле не имеет значения, являются ли клиенты локальными или удаленными
  • не так много дополнительной работы для приложений на основе какао

Документация может показаться, что это больше похоже на работу, чем на самом деле, но все, что вам в основном нужно сделать, это правильно использовать протоколы и экспортировать или, соответственно, подключаться к корневому объекту сервера.
Остальное должно произойти автоматически за кулисами для вас в данном сценарии.

Мы используем ThoMoNetworking, и он отлично работает и быстро настраивается. В основном это позволяет отправлять объекты, совместимые с NSCoding, в локальную сеть, но, конечно, также работает, если клиент и сервер находятся на одной машине. Как оболочка для базовых классов, она заботится о сопряжении, переподключениях и т. Д.

Другие вопросы по тегам