As long as both client and server are OS X apps and can both be written in Objective-C using the Cocoa frameworks, I would highly recommend you take a look at the Distributed Objects (DO) technology in Cocoa. I won't try to give a tutorial in Distributed Objects here, just explain why it might be useful...
DO handles asynchronous network details for you (all your client updates could happen on a single thread). In addition the semantics of communication with a remote object (client to server or visa versa; DO is bidirectional once the connection is established) are very similar to in-process communication. In other words, once you have a reference to the remote object (really an NSDistantObject
which acts as a proxy to the object on the other end of the connection), your client code can send messages to the remote object as if it were local:
[remoteServer update:client];
from the client or
[[remoteClientList objectAtIndex:i] update:server];
from the server. I'll leave the details of setting up the connection and for getting the remoteServer or remoteClient reference to you after reading the Distributed Objects programming guide.
The downside of using DO is that you are tied to Cocoa; it will be very difficult to write a non-Cocoa client or server that communicates using Distirbuted Objects. If there's a chance you may want to have non-Cocoa client or server implementations, you should not use DO. In this case, I would recommend something simple with a lot of cross-platform and language support. A REST-style API over HTTP is a good option. Have a look at the Cocoa URL Loading System documentation for info on how to implement HTTP requests and responses. Have a look at Apple's CocoaHTTPServer example code or a code.google.com project of the same name for info on implementing an HTTP server in your Cocoa code.
As a very last option, you can take a look at the Cocoa Stream Programming Guide if you want to implement your own network protocol. NSStream
's subclasses will let you listen on a network socket and handle asynchronous reads/writes to/from that socket. A lot of people use AsyncSocket for this purpose. It wraps the (lower-level) CFStream and CFSocket and makes writing network code somewhat easier.