Meilleure façon de faire la communication interprocess sur Mac OS X

Je cherche à construire une application Cocoa sur le Mac avec un processus démon back-end (vraiment juste une application Cocoa sans tête, probablement), avec 0 ou plusieurs applications "clientes" exécutées localement (bien que si possible, je voudrais également prendre en charge les clients distants; les clients distants ne seraient jamais d'autres Mac ou appareils iPhone OS).

Les données communiquées seront assez triviales, principalement du texte et des commandes (qui, je suppose, peuvent être représentées sous forme de texte de toute façon), et peut-être le petit fichier occasionnel (une image éventuellement).

J'ai regardé quelques méthodes pour le faire mais je ne suis pas sûr de ce qui est "le meilleur" pour la tâche à accomplir. Les choses que j'ai considérées:

  • lecture et écriture dans un fichier (...oui), très basique mais pas très évolutif.
  • sockets purs (Je n'ai aucune expérience avec les sockets mais il me semble que je peux les utiliser pour envoyer des données localement et sur un réseau. Bien qu'il semble lourd si tout faire dans le cacao
  • objets distribués: semble plutôt inélégant pour une tâche comme celle-ci
  • NSConnection: Je ne peux pas vraiment comprendre ce que cette classe fait même, mais j'en ai lu dans certains résultats de recherche IPC

Je suis sûr qu'il y a des choses qui me manquent, mais j'ai été surpris de constater un manque de ressources sur ce sujet.

23
demandé sur Georg Fritzsche 2010-05-17 06:22:01

3 réponses

Je me penche actuellement sur les mêmes questions. Pour moi la possibilité d'ajouter des clients Windows, plus tard, rend la situation plus compliquée; dans votre cas, la réponse semble être plus simple.

À propos des options que vous avez envisagées:

  1. Fichiers de contrôle: Bien qu'il soit possible de communiquer via des fichiers de contrôle, vous devez garder à l'esprit que les fichiers doivent être communiqués via un système de fichiers réseau entre les machines impliquées. Donc le système de fichiers réseau sert d'abstraction de l'infrastructure réseau réelle, mais n'offre pas la pleine puissance et la flexibilité du réseau normalement. implémentation: pratiquement, vous devrez avoir au moins deux fichiers pour chaque paire de clients / Serveurs: un fichier que le serveur utilise pour envoyer une requête au(X) client (s) et un fichier pour les réponses. Si chaque processus peut communiquer dans les deux sens, vous devez le dupliquer. En outre, le(S) client(s) et le (s) serveur (s) fonctionnent sur une base "pull", c'est-à-dire qu'ils besoin de revoir les fichiers de contrôle fréquemment et voir si quelque chose de nouveau a été livré.

    L'avantage de cette solution est qu'elle minimise le besoin d'apprendre de nouvelles techniques. Le gros inconvénient, c'est qu'il a d'énormes pressions sur la logique du programme; beaucoup de choses doivent être prises en charge par vous (les fichiers Seront écrits en un seul morceau ou peut-il arriver qu'une partie ramasse les fichiers incompatibles? À quelle fréquence les contrôles devraient-ils être mis en œuvre? Ai-je besoin de s'inquiéter à propos du système de fichiers, comme la mise en cache, etc? Puis-je ajouter le cryptage plus tard sans jouer avec des choses en dehors de mon code de programme? ...)

    Si la portabilité était un problème (ce qui, pour autant que j'ai compris de votre question n'est pas le cas) alors cette solution serait facile à porter vers différents systèmes et même différents langages de programmation. Cependant, je ne connais aucun fichier réseau ystem pour iPhone OS, mais je ne suis pas familier avec cela.

  2. Sockets: L'interface de programmation est certainement différent; en fonction de votre expérience avec la programmation de socket, cela peut signifier que vous avez plus de travail à l'apprendre en premier et à le déboguer plus tard. implémentation : pratiquement, vous aurez besoin D'une logique similaire à celle d'avant, c'est-à-dire que le(S) client(s) et le (s) serveur (s) communiquent via le réseau. Un avantage certain de cette approche est que les processus peuvent fonctionner sur une base "push", c'est-à-dire qu'ils peuvent écouter sur un socket jusqu'à ce qu'un message arrive, ce qui est supérieur à la vérification régulière des fichiers de contrôle. Réseau la corruption et les incohérences ne sont pas non plus votre préoccupation. En outre, vous (pouvez) avoir plus de contrôle sur la façon dont les connexions sont établies plutôt que de compter sur des choses en dehors du contrôle de votre programme (encore une fois, cela est important si vous décidez d'ajouter le cryptage plus tard).

    L'avantage est que beaucoup de choses sont enlevées de vos épaules qui dérangeraient une implémentation en 1. L'inconvénient est que vous devez toujours changer considérablement la logique de votre programme afin de faire assurez-vous que vous envoyez et recevez les informations correctes (types de fichiers etc.).

    Dans mon expérience, la portabilité (c'est-à-dire la facilité de transition vers différents systèmes et même des langages de programmation) est très bonne car tout ce qui est même compatible à distance avec POSIX fonctionne.

    [EDIT:, En particulier, dès que vous communiquer des nombres binaires endianess devient un problème et vous devez prendre soin de ce problème manuellement - c'est l'un des (!) cas particulier des " informations correctes" question je l'ai mentionné ci-dessus. Il vous mordra par exemple lorsque vous avez un PowerPC qui parle à un Mac Intel. Ce cas particulier disparaît avec la solution 3.+4. ensemble, tous les autres problèmes "d'information correcte".]

  3. +4. objets distribués: le cluster de classes NSProxy est utilisé pour implémenter des objets distribués. NSConnection est responsable de la configuration des connexions distantes comme condition préalable à l'envoi d'informations, donc une fois que vous comprenez comment utiliser ce système, vous pouvez également comprendre les objets distribués. ;^)

    L'idée est que votre logique de programme de haut niveau n'a pas besoin d'être modifiée (c'est-à-dire que vos objets communiquent via des messages et reçoivent des résultats et que les messages ainsi que les types de retour sont identiques à ce à quoi vous êtes habitué de votre implémentation locale) sans avoir à vous soucier des détails de Eh bien, au moins en théorie. implémentation: je travaille aussi sur cela en ce moment, donc ma compréhension est encore limitée. Pour autant que je sache, vous devez configurer une certaine structure, c'est-à-dire que vous devez toujours décider quels processus (locaux et/ou distants) peuvent recevoir quels messages; c'est ce que fait NSConnection. À ce stade, vous définissent implicitement une architecture client/serveur, mais vous n'avez pas besoin de vous soucier des problèmes mentionnés au 2.

    Il y a une introduction avec deux exemples explicites sur le serveur de projet Gnustep; elle illustre le fonctionnement de la technologie et constitue un bon point de départ pour l'expérimentation: http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_7.html

    Malheureusement, les inconvénients sont une perte totale de compatibilité (bien que vous ferez toujours bien avec la configuration que vous avez mentionné des Mac et iPhone/iPad seulement) avec d'autres systèmes et la perte de portabilité vers d'autres langues. Gnustep avec Objective-C est au mieux compatible avec le code, mais il n'y a aucun moyen de communiquer entre Gnustep et Cocoa, voir mon édition pour la question numéro 2 ici: CORBA sur Mac OS X (Cocoa)

    [EDIT: je suis juste tombé sur une autre information que je ne connaissais pas. Bien que j'ai vérifié que NSProxy est disponible sur l'iPhone, je n'ai pas vérifié si les autres parties du mécanisme des objets distribués le sont. Selon ce lien: http://www.cocoabuilder.com/archive/cocoa/224358-big-picture-relationships-between-nsconnection-nsinputstream-nsoutputstream-etc.html (recherchez la page pour l'expression "iPhone OS" ) ils ne sont pas. Cela exclurait cette solution si vous demandiez d'utiliser iPhone / iPad en ce moment.]

Donc, pour conclure, il y a un compromis entre l'effort d'apprentissage (et la mise en œuvre et le débogage) de nouvelles technologies d'une part et le codage manuel de la logique de communication de niveau inférieur d'autre part. Alors que l'approche de l'objet distribué prend le plus de charge de vos épaules et subit les plus petits changements dans la logique du programme, c'est le plus difficile à apprendre et aussi (malheureusement) le moins portable.

15
répondu user8472 2017-05-23 12:26:00

Avertissement: Les objets distribués sont non disponibles sur iPhone.


Pourquoi trouvez-vous objets distribués inélégante? Ils ressemblent à un bon match ici:

  • groupement transparent des types fondamentaux et des classes Objective-C
  • peu importe si les clients sont locaux ou distants
  • pas beaucoup de travail supplémentaire pour les applications à base de cacao

La documentation pourrait sembler plus de travail ensuite, il l'est réellement, mais tout ce que vous avez à faire est d'utiliser les protocoles proprement et d'exporter, ou respectivement de vous connecter à, l'objet racine des serveurs.
Le reste devrait se produire automagiquement dans les coulisses pour vous dans le scénario donné.

13
répondu Georg Fritzsche 2010-05-23 20:50:43

Nous utilisons ThoMoNetworking et cela fonctionne très bien et est rapide à installer. Fondamentalement, il vous permet d'envoyer des objets compatibles NSCoding dans le réseau local, mais fonctionne bien sûr aussi si le client et le serveur sont sur la même machine. En tant que wrapper autour des classes de fondation, il s'occupe de l'appariement, des reconnexions, etc..

6
répondu NSSplendid 2010-05-26 14:25:41