2009-02-19 10 views
11

Ich baue eine Objective-C App, die sowohl einen Server als auch einen Client hat. Der Client kann Updates an den Server senden, und der Server muss Updates für jeden verbundenen Client senden können. Ich habe darüber nachgedacht, wie dieses System am besten zu implementieren ist, aber ich frage nach Ihren Vorschlägen.Ziel-C-Vernetzung - Best Practices?

Momentan denke ich, dass wenn neue Updates verfügbar sind, der Server Threads verwendet, um das Update nacheinander an jeden Client zu senden. Wenn ein Client das Zeitlimit überschreitet, wird die Verbindung getrennt. Ich habe sehr wenig Networking-Erfahrung, so frage ich Ihre Einsicht.

Glauben Sie, dass dieses System gut funktionieren würde? Wenn ja, haben Sie Vorschläge für das Threading? Irgendwelche NS-Klassen, auf die du mich verweisen kannst? Es muss eine Art Warteschlange geben, die ich benutzen kann, denke ich.

Irgendwelche anderen Gedanken?

EDIT: Ich erwarte nicht, dass die Client-Zählung viel über 50 oder so, bei der max.

+0

Wenn ich das wieder tun würde, würde ich AMQP oder ein ähnliches Messaging-Protokoll in Erwägung ziehen, damit Updates als Push durchgeführt werden können. Nur zum Nachdenken. – Allyn

Antwort

10

Solange sowohl Client als auch Server OS X-Anwendungen sind und beide in Objective-C mit den Cocoa-Frameworks geschrieben werden können, würde ich Ihnen wärmstens empfehlen, die Distributed Objects (DO) -Technologie in Cocoa zu betrachten. Ich werde nicht versuchen, ein Tutorial in Verteilte Objekte hier zu geben, nur erklären, warum es nützlich sein könnte ...

DO behandelt asynchrone Netzwerkdetails für Sie (alle Ihre Client-Updates können in einem einzigen Thread passieren). Zusätzlich ist die Semantik der Kommunikation mit einem entfernten Objekt (Client zu Server oder umgekehrt; DO ist bidirektional, sobald die Verbindung hergestellt ist) sehr ähnlich zur In-Prozess-Kommunikation. Mit anderen Worten, sobald Sie einen Verweis auf das Remote-Objekt haben (wirklich eine NSDistantObject, die als Proxy für das Objekt am anderen Ende der Verbindung fungiert), kann Ihr Client-Code Nachrichten an das Remote-Objekt senden, als wäre es lokal:

[remoteServer update:client]; 

vom Client oder

[[remoteClientList objectAtIndex:i] update:server]; 

vom Server. Ich werde die Details zum Einrichten der Verbindung und zum Abrufen der remoteServer oder remoteClient-Referenz an Sie nach dem Lesen der Distributed Objects programming guide verlassen.

Der Nachteil der Verwendung von DO ist, dass Sie an Kakao gebunden sind; Es wird sehr schwierig, einen Nicht-Cocoa-Client oder -Server zu schreiben, der mithilfe von Distibruted Objects kommuniziert. Wenn es eine Chance gibt, dass Sie nicht-Cocoa-Client- oder Server-Implementierungen haben möchten, sollten Sie DO nicht verwenden. In diesem Fall würde ich etwas Einfaches mit viel plattformübergreifender und sprachlicher Unterstützung empfehlen. Eine REST-ähnliche API über HTTP ist eine gute Option. In der Dokumentation von Cocoa URL Loading System finden Sie Informationen zum Implementieren von HTTP-Anforderungen und -Antworten. Werfen Sie einen Blick auf Apples CocoaHTTPServer Beispielcode oder ein code.google.com-Projekt der same name für Informationen zum Implementieren eines HTTP-Servers in Ihrem Cocoa-Code.

Als allerletzte Option können Sie sich den Cocoa Stream Programming Guide ansehen, wenn Sie Ihr eigenes Netzwerkprotokoll implementieren möchten. Mit den Unterklassen NSStream können Sie auf einen Netzwerk-Socket warten und asynchrone Lese-/Schreibvorgänge für diesen Socket durchführen. Viele Leute benutzen AsyncSocket für diesen Zweck.Es umschließt den (untergeordneten) CFStream und CFSocket und macht das Schreiben von Netzwerkcode etwas einfacher.

+1

Wenn Sie DO in einer plattformübergreifenden Anwendung verwenden möchten, kann GNUStep sehr helfen, obwohl Sie an dieser Stelle wahrscheinlich nicht GNUStep für die GUI verwenden möchten. – user57368

+0

Ah, guter Punkt. Ich habe überhaupt nicht mit den verteilten GNUStep-Objekten gespielt, daher kann ich es nicht empfehlen, aber es lohnt sich, nach dem OP zu suchen. –

+0

Ich habe bereits verteilte Objekte ausprobiert und ausgeschlossen; sie sind einfach nicht geeignet. Ich schätze die Links jedoch. Ich hätte erwähnen sollen, dass ich bereits eine partielle Implementierung mit AsyncSocket habe. – Allyn

2

Wenn der Server Updates an die Clients sendet, ist es wahrscheinlich einfacher, wenn nur ein Thread sie alle behandelt und nur asynchrone Sockets verwendet. Das hängt natürlich davon ab, mit wie vielen Kunden Sie ebenfalls zu tun haben.

0

Ich weiß nicht, wie Sie planen Sie System zu entwerfen, aber in der Regel ein Server an einen Client keine Verbindung herstellen kann; Der Client muss die Kommunikation initiieren. Mit einer niedrigen Grenze von 50 Clients, können Sie nicht eine Web-Server/Client-ähnliche Implementierung ...

Das heißt, es gibt im Wesentlichen zwei Möglichkeiten, Client-Server-Kommunikation zu behandeln: 1. Der Client fragt ab Der Server erhält regelmäßig Updates 2. Der Client hält eine Verbindung offen für den Server und der Server antwortet mit einem bekannten (wie in beiden Seiten verstehen) Protokoll.

2

Auf der Apple-Entwicklerseite gibt es mehrere Netzwerkbeispiele. Ein Ich würde empfehlen, dass Sie die URLCache, die heruntergeladen werden kann, auschecken. aus der Dokumentation des Apple-Quoting für dieses Beispiel:

Urlcache ist ein Beispiel iPhone-Anwendung, die wie eine Ressource aus dem Internet herunterladen zeigt, sollte sie in das Datenverzeichnis der Anwendung, und die lokale Kopie der Ressource verwenden. Urlcache zeigt auch, wie ein paar Cache-Strategien implementieren:

2

Eine interessante Option ist das BLIP Protokoll von Jens Alfke. Es ist wie eine abgespeckte Version von BEEP: ein nachrichtenorientiertes Netzwerksystem. Es stellt im Grunde die Low-Level-Abstraktionen für eine bidirektionale Nachrichtenleitung bereit, so dass Sie sich darauf konzentrieren können, Ihr Kommunikationsprotokoll darüber zu schichten.

Es hat einige würdige Anhänger wie Marcus Zarra (Autor der CoreData Bibel) und Gus Mueller von Flying Meat Software.