serious, “roll your own” networking Use cases: non-web clients (mail, chat, etc.), games, telephony, anything that is real-time oriented and wants to avoid polling a server.
service... • Push notifications • Publish/subscribe systems like Faye or pusher.com; XMPP • Maintain a long-lived connection to a server and be notified by it • Be prepared to reconnect and switch from cellular back to Wi-Fi Apple’s push notifications are meant for small messages to poke a client to make a request to the server. No delivery guarantees. PubSub systems cut out Apple as a middleman (more reliably delivery) at the expense of additional server resources and maintenance costs.
end) • Reliable (guaranteed error-free, in- order delivery) • Stream-based UDP • Connectionless • Unreliable • Datagrams A TCP stream is like a file: you can read it in chunks of your choosing. By contrast, UDP isn’t a stream. A UDP datagram must be read in its entirety or you lose the rest of the bytes. While UDP has a checksum field, it isn’t always verified. If it is checked and it doesn’t match, the datagram is simply dropped. The sender never retransmits.
• Streams are blocking • Schedule them on a run loop or set up GCD event sources Blocking is your biggest hurdle. Often you want to send and receive complete messages, but to do this you’ll need to wrap the stream objects and do the buffering yourself.
for listening in CFNetwork • For CFSocket, create run loop sources • For POSIX sockets, create dispatch sources • IPv6: evaluate dual-bound listener Oddly, Apple says if you’re writing code exclusively for OS X and iOS, to use the POSIX API to create the listener. This sounds fishy; I think the technical writer meant to say CFSocket. In 2010, Apple recommended creating a dual-bound listener, but absent from recent WWDC videos. There is debate about if this is a good idea (e.g., OpenBSD will never do this).
sockets and GCD event sources, while the client uses CFStream and the run loop. Both are contained in one app and demonstrate how you must buffer writes to avoid blocking.
• Easy to do for clients [inStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey]; NSDictionary *properties = @{ kCFStreamSSLValidatesCertificateChain: @NO }; CFReadStreamSetProperty((CFStream *)inStream, kCFStreamPropertySSLSettings, (CFTypeRef)properties)); Secure servers are necessarily more complex for two reasons. First, you have to dip down a layer to listen, so the stream properties aren’t available. Second, the server half requires a certificate and private key.
find those services • No IPs, no ports: “zero configuration” • However: local subnet only Demo the same echo app, only using Bonjour to find the server instead of entering host and port. Communication code is exactly the same, but server publishes via NSNetService after binding the listener socket and the client looks for Bonjour services instead of asking for a host and port in the UI.
Implemented using Bonjour Though it uses Bonjour, I was not able to get an iOS GameKit client to connect to a Mac Bonjour service. Demo the simple chat app. Since GameKit is also available on Mountain Lion, it would be straightforward to write a chat app that can talk between OS X and iOS.