Simplifying Networking Using Bonjour

Session 205 WWDC 2010

Bonjour, also known as zero-configuration networking, enables automatic discovery of computers, devices, and services on IP networks. A wide range of Apple's products, from iMacs and MacBooks to AirPort Base Stations and Time Capsules, Apple TVs to iPhones, iPod touches and iPads use Bonjour for streamlined and reliable networking. Learn how to use Bonjour to make it easy for your applications to publish, discover, and resolve network services.

Stuart Cheshire: Good morning ladies and gentlemen.

It's good to see you all here today.

My name is Stuart Cheshire and I'm the architect of Bonjour.

I'm going to be telling you today about Bonjour and related technologies and particularly about how it interacts with multitasking on iOS 4.

Let me ask how many people are here at their first WWDC.

Can I see a show of hands?

That is amazing.

That's more than half the room.

And how many are here for the first time at a Bonjour presentation.

OK. Then I'm glad we have some overview because this is the first time for I'd say about 80% of the people in the room.

In previous years, what I'm going to talk about is the overview would have been the entire hour-long presentation.

We have a lot more stuff to talk about today so it's going to be very condensed but I hope it'll give you the flavor of what it's about and at least point you in the right direction for more documentation to find out more details.

Rory McGuire, my colleague will be telling you about some specific details of Bonjour on iPhone OS and will be talking about some other developments because Bonjour is not just a Mac technology.

It's not just an Apple technology.

We have Bonjour on Windows and there are many third party products using Bonjour as well.

It is an open standard.

The source code is open source under the Apache 2 license and all the specifications of public.

We'll wrap up with some tips and reminders of common mistakes that which developers make so that you can avoid making the same mistakes.

So let's start with the high level goal.

TCP/IP, the technology of the internet clearly won out against all the other wide area of technologies like DECnet and XNS, X.25, ISDN and it was a great achievement to build a global scale network.

But where it lacked was ease of use and the canonical example I like to give is you take a USB printer, you take the cable, you plug it in.

Nobody has to type addresses and subnet masks and configuration parameters to make that USB work.

And there's no technical reason why IP can't be just as easy as that.

The only reason is that all the people working on it in the early days were so focused on the challenge of building a global network to rival the telephone system that they totally neglected worrying about the details of two computers connected with a cable because that seems so trivial in comparison.

What we did with Bonjour and zero configuration networking is to go back and fill in that missing piece.

So when you're designing your application or your hardware product, if you have any doubts about a certain design decision, kind of mentally think, if I plug it into USB, what would I expect.

We would like the same user experience with an Ethernet cable or with Wi-Fi or with IP or with Bluetooth.

So that's the goal.

We want networking where you just plug it and it works.

This is how we achieve that goal.

And there are three legs of technology that make up the foundation for Bonjour, zero configuration networking and that foundation is what lets you developers write applications where you can rely on networking being present and functional and not have to worry about a lot of failure modes that you used to have and I'll start up with one of those failure modes.

DHCP is great.

We are not competing with DHCP at all and if you have a DHCP server on the network handing out addresses, that's great.

But if you don't, if you just have two devices connected with an Ethernet cable or some devices connected to a simple Ethernet switch, then there's no DHCP server.

And in the past, most devices would just give up.

So you can't find DHCP server and refuse to work until the user fix the problem.

Now for desktop computer with a screen and a keyboard, that's annoying but it's not fatal because the user can configure a manual address.

But for devices that don't have a screen and a keyboard, for device like an AirPort Extreme Base Station where it's only user interface for controlling it is over the network.

It has got to get itself on the network.

Because if its network is misconfigured so it can't communicate, you have no way of communicating with it to fix that.

So IPv6 has link-local addressing.

Every IPv6 device configures itself a link-local address on every interface which is not configured by the user.

The user can't break that so you can rely on it to have an address and with RC3927, we have the same thing in IPv4 and you've probably seen this now.

This is not new.

Ten years ago when we're talking about this, this was new.

These days everyone in the room is probably familiar with those addresses 169.254 and that means the machine picked its own address because it couldn't find the DHCP server to give it another address.

So this is a good start.

We can have two or three or five machines all with self-assigned unique addresses but it doesn't really help you if you don't know what the address is and nobody likes typing addresses especially IPv6 addresses.

With conventional IP, people are used to using DNS host names.

So following a similar principle that we want to stay as close as possible to our current practices, we use Multicast DNS which uses the same naming syntax, the same record types, the same resource record types and the same packet format of standard DNS but without a central server.

And every device on the network has a piece of software which is the Multicast DNS responder which knows that device its own name.

And when the client multicast a query to every device on the network, the one that recognizes its name says, hey, that's me and it answers the query.

Now that's good.

That's got us to parity with what people expected of the internet 10 years ago but you still have to know the name to type and if you type it wrong, it doesn't work and you don't really know why.

So we wanted to go one step beyond that and that's the third item on this list of technologies and that's service discovery.

Building on the Multicast DNS mechanisms, we can also multicast queries to the network.

Not for specific host name but for type of service.

Say, I want to print.

What devices out there can meet that need for me?

What printers are out there that I can turn a printer up too that results in sheets of printed paper coming out.

And that service discovery is the third leg and that's the level that you as developers will generally be interacting with this.

Because the addressing is handled by the OS, so unless you're building hardware devices, you don't need to do that and the host name lookup is an OS level function.

But if you are offering services on the network and that means if you have a socket that's listening or if you're making connections on the network, you'll want to interact with the service discovery APIs that Bonjour provides on the Mac, on iOS, on Windows and on other platforms.

So here's an overview.

You have a piece of software that's listening for connections.

That's great and you can make the user write down the port number on a post-it note but it's better to use the technology we have to advertise that fact on the network.

When your service starts up or when the machine wakes from sleep or when you connect the network, it sends out a couple of announcement packets to let clients that may be listening know that this service is now on the network.

Now it's not continuously broadcasting its pockets because that would add up to a lot of wasted bandwidth but it does send out a few packets on startup.

Now suppose a client comes along and were looking for that service.

The client will do a browse operation and these APIs were available in C and in Cocoa and in Java, in different languages, but they all have the common property that you browse the services and the server responds if it has an instance of that service type.

So this lets the client build a list to present to the user so the user can pick which particular instance they want to connect to.

And then the second step is resolving that name service to get the current IP address and port number where that service can be reached and this is a very important point with Bonjour.

Browsing and resolving are separate, other service discovery protocols didn't make this separation and the reason it's important is because, I'll go back to the familiar example of printing.

Browsing the network defined which printers are available and picking the one you're going to use most of time is your default prints out.

It's an operation that people do relatively infrequently.

Some people may only do it once a year.

They pick a printer and then they don't change it at work.

But with DHCP, with link-local addressing, addresses and ports can change overtime and if your printer preferences on your machine have stored the address and port number, that might not work tomorrow.

But the names are stable overtime.

So by storing the name and then resolving on use, you get the current address information.

So this is very important, we'll come back to this later.

Browse to show the use of the list but then resolve a connection time to find the most up-to-date information.

That was on the local network.

One of the questions we knew that would come up is, well this is great on the local link but what about across the internet.

What if I'm behind the NAT Gateway and the answer is the same Bonjour APIs that work with link-local Multicast DNS also work with wide area Bonjour and the area where most of you are probably most familiar with this, is this is the underlying technology between Back to My Mac in MobileMe.

So when you're using screen sharing and file sharing to access your machine across the other side of the country, it's wide area Bonjour and the standard Bonjour APIs that are doing that for you and if you have an application that registers with Bonjour and browses with Bonjour, then your application will work planet-wide using Back to My Mac as well.

It's not just screen sharing and file sharing.

It supports all of your apps as well.

This is the API architecture.

On top of the kernel, we have a daemon called mDNSResponder running and clients talk to that daemon to advertise services and browse the services.

There are three main levels of API here not counting Java and Python and Ruby and some of the other languages.

There's the dns_sd.h which is the low-level C programming API.

That's available on Mac, Linux, Windows and on the iPhone.

The next level up is core foundation CFNetServices and the highest layer is NSNetServices which is the foundation layers used by Cocoa.

And for most of you in this room doing iOS development, you'll probably be working at the NSNetServices layer but they are all available on the iPhone.

So if you got existing code, you can still use that.

So Bonjour started off as replacing the AppleTalk Chooser to define what's on the local network.

But when you use the Bonjour APIs you get a lot more than that.

I've talked about discovering local things.

I've talked about discovering remote things by Back to My Mac.

I'm going to tell you about discovering devices that may be asleep.

This is the new feature we introduced with Snow Leopard, we talked about last year.

I'll give a little recap of that now.

And we keep inventing new communication technologies and they come along with their own sets of APIs and their own addressing syntax and their own model for how they work and that can be a burden for developers to have to keep supporting whatever the new thing is.

So one of the great things I was very excited about last year with iPhone OS 3 is peer-to-peer Bonjour over Bluetooth.

So you don't have to pair Bluetooth.

You don't have to configure it.

You don't have to set up the Bluetooth panel, configure the IP addresses.

You just use the Bonjour APIs and when you're resolved, we will actually bring up an IP network over Bluetooth on demand and then connect you to the other device.

And this is what's used by the Game Kit on iPhone.

But it's actually implemented as a Bonjour function so all of your Bonjour apps get this for free as well.

So let's talk about the sleeping case.

Suppose I've got a USB printer plugged into my Mac with printer sharing and this is great because I can print remotely.

I can be sitting on the sofa with my laptop and I can print.

But not if the computer is asleep.

Back to My Mac, similar story.

I can get to my computer remotely but not if it's asleep.

Apple TV can access music and movies and photos of my iTunes music collection on my iMac but not if it's asleep.

So on the one hand, customers want to put their machines to sleep so they're not wasting energy but on the other hand, we keep providing useful services to them that mean they want to keep the machine awake and we wanted to resolve this tension and make it so that you can have the best of both worlds and that's the Bonjour Sleep Proxy.

The Bonjour Sleep Proxy runs on AirPort Base Stations.

It runs on Apple TV because that's the device that's always on, on your network and doesn't take very much power.

If you're running internet sharing on your Mac, then that will also act as a sleep proxy.

Basically, any device that doesn't take much power that's always on is a great candidate for a sleep proxy.

It's open source so anybody can make these but for most of you in the room, I'm guessing your AirPort Base Station is going to be your proxy.

When the Mac goes to sleep, it takes its Bonjour service records and ships them in a packet to the proxy.

Because those service records are a compact representation of its role on the network, what its name is, what its address is, what services it offers, what ports it's listening on, it takes all that information and ships it to the proxy and says this is me, I'm going to sleep now, wake me up if anybody wants me.

The iMac goes to sleep and the proxy sends out some proxy out packets to say, I am now temporarily responsible for this IP address because I'm proxying for the device that's asleep.

Now on my other machine, I have a document that I want to print.

So it looks up the address and port, find the Bonjour result and it opens a TCP connection and that TCP SYN goes to the proxy.

Because the proxy is currently the owner of that IP address.

The proxy inspects that packet and decides that this is something that warrants waking up the sleeping machine.

So it sends a wake-up-packet and the machine wakes up.

It reclaims its IP address, TCP in the normal course of operation will retransmit the packet which now goes to the newly awakened machine and the document successfully prints.

Many of you may have had this happen without even realizing it because like all good networking technologies, it's frequently completely invisible.

You notice it when it fails.

If you hit command-P and the document doesn't print and you kind of curse, oh my, My Mac has gone to sleep, let me get up and wake it up, then you notice it.

But if you hit Print and the page comes out, you may never have even realized that your machine was asleep.

It woke up to print the document and then it went back to sleep.

And this is really rewarding when networking technology works that well.

It can also be a little bit disappointing that we're doing all this work to make this magic work and nobody even notices.

[ Laughter ]

So it's printed the document, my machine goes back to sleep.

That was in the case where the client already knows about the printer because I've set it up as my default printer but because of Bonjour service advertising, a friend could come and visit my house with a laptop computer and they've never been on my network before.

They've never used my printer before but when they do Bonjour browsing operation, the proxy responds on behalf of the sleeping machine saying there's a printing service on this network and it does that without even having to wake the machine.

So unlike other Wake-on-LAN technologies that have been around for a few years, you don't need manual setup in advance to configure this.

You can walk into a network you've never been on before and still discover services even on machines that are asleep.

[ Pause ]

Bonjour sleep proxy works with any application that uses the Bonjour APIs.

So we use it for printer sharing.

We use it for Apple TV accessing iTunes.

Even outside the house, if you want to get back to your Mac at home and the Mac's asleep, the base station will wake it up when an incoming connection comes in.

With command-line ssh, this is not something that normal users use but the developers tend to love this.

You can be logged in to a machine with ssh and when you're finished doing what you're doing, type pmset sleepnow and the machine will go to sleep without losing your TCP connection.

Sometime later, you type in that window, first keystroke, the machine wakes back up, does what you want, put it back to sleep again.

You can keep your connection open for days or weeks at a time to a machine that will sleep and wake on demand and it doesn't have to awake consuming power 24 hours a day bust because you've got an ssh log into that machine.

And for all of your applications that advertise services with Bonjour, if you advertise your service, we can transfer that data to the sleep proxy.

If you don't advertise the service, we don't know about you and we can't tell the proxy about you.

So with that, I'd like to invite Rory McGuire to come up on stage and tell you some specific details about Bonjour and multitasking in iPhone OS.

[ Applause ]

Rory McGuire: Thank you Stuart.

My name is Rory and I'm here to help you learn about Bonjour on iPhone OS.

Specifically, we're going to go over three things.

First is peer-to-peer networking, something that Stuart talked about a little bit.

I'll go into a little bit more detail.

The second is a new API in iOS 4 called DNSServiceSetDispatchQueue.

It's in our low-level C API and it allows you to use GCD queues with Bonjour.

It'll make things a lot easier for you, I'll get into that.

And the new hotness for iOS 4 multitasking and what that means for Bonjour and networking in general.

Let's get to it.

Peer-to-peer, this is something that we introduced last year with iPhone OS 3.

You may know this as being used by Game Kit.

Well, what does it actually do?

I'm sure we're all familiar with this Wi-Fi selection UI, Wi-Fi network selection UI.

Which network do I pick, right?

Let's say for example that you're in a room with 576 MiFis.

If I wanna use my game or use my service, which one of these things do I pick?

Well, we're going to solve that with no configuration.

How are we going to do it?

Bluetooth.

But wait a second.

This is the Bonjour session, what are we doing talking about Bluetooth?

Well it's Bonjour over Bluetooth.

Again, like Stuart said, there's no manual pairing.

Bonjour will automatically make the devices connect when you do a resolve.

Again, this is used by Game Kit but it's not required that you use Game Kit.

You only really have to use the Bonjour APIs.

So if you already have the Bonjour APIs in your app, you will get the Bluetooth stuff for free.

How is it the same?

Exactly the same APIs, NSNetService APIs, CFNetService APIs and the dns_sd low-level C API.

Your code will just work.

How was it different?

Well, Stuart talked a little bit about how Bonjour actually separates browsing from resolving.

This really worked well for us to implement this over Bluetooth.

Resolves may take a little bit longer because that's what actually tells Bonjour to bring up the IP connection, the PAN connection between the two devices.

So one of the things that you're going to want to is make sure you use ResolveWithTimeout.0.

It's going to take a little bit longer than a connection, a resolve over Wi-Fi.

Let the user decide when they've waited long enough for this thing to come up.

That's about it.

So, let's go to little more detail about the separation between browse and resolve.

Browsing gets you a little bit of information about a lot of service instances.

It gets you the name of lots and lots of service instances.

Resolve on the other hand gets you a little bit of info or gets a lot of information about one particular instance.

And in the case of Bonjour over Bluetooth, it also brings up the Bluetooth PAN connection which is kind of a heavyweight operation.

What you don't want to do is resolve every single service that you find in the browse because that's going to fill in the whole table and it's going to be very costly.

Don't browse continuously because that also has some power and performance implications.

Don't resolve every service.

You can get a little bit more information about the services by querying for the TXT record.

There are APIs at the NS and CF layer to get the TXT record for the services that your browses return so you can display a little bit more information to the user.

But let your user decide which service they want to connect to.

Don't just go off connecting to every single service because you're going to be telling Bluetooth to go off and connect to these different PAN connections if the thing was discovered over Bluetooth.

You don't want your app to be known as the one that drains the user's battery.

Not to be outdone, the Wi-Fi guys are actually working on something called Wi-Fi Direct.

This is currently scheduled to have Bonjour in it.

Alright, it does some exchange with these people to actually have this work as well using Bonjour.

What that's going to mean for you is that you'll just use the Bonjour APIs.

Just like over Bluetooth, it's just going to work.

But of course, it's not out yet.

Next topic, DNSServiceSetDispatchQueue.

This a new API in iOS 4 and it's actually quite nice.

It's very, very simple.

You have a DNSServiceRef and you tell it, this is the queue I want to put it on.

Before this API, when you use the low-level C APIs for Bonjour, you would have to create a CF socket run loop source or you would have to have your own kqueue loop or your own select loop.

You'd have to call DNSServiceProcessResult or all these things you had to do in order to get it to work with the C API.

Now, however, it's going to be just one line of code, right?

You start up your browse like you did previously, but now instead of creating and putting something in your select loop and calling DNSServiceProcessResult or creating a CFRunLoop source, all you have to do is call the SetDispatchQueue with your DNSServiceRef and the queue you want to put it on.

In most cases, it's going to be the main queue.

Now if you're new to iPhone development or actually you're just new to iPhone OS 4, to iOS 4, GCD is seriously the coolest thing since sliced bread.

I love GCD.

There is the GCD on iOS session immediately following this one in Russian Hill.

I invite everybody to attend that, please.

That's it for that API.

It's really simple.

Now on to the new hotness, multitasking.

So we're going to go through a timeline here.

What happens when your a standard multitask in your app.

Now, there's some other kinds of apps you can be.

You can be a VoIP app.

You can do some things with locations, things like that.

I'm not going to cover those.

Those are covered by the multitasking sessions.

I'm going to talk about general networking in applications that are not VoIP and not doing audio streaming and things like that.

The first thing that's going to happen when the user hits the Home button is that you're going to get the applicationDidEnterBackground callback on you application delegate.

At some point after that, your code is going to stop running.

Now, you can request a task completion and that'll extent the amount of time that you get to run but not really all that much, right.

At some point, your app is going to be not be scheduled anymore by the kernel.

There is no indication when your application actually stops running.

The only indication that you get is that your application did enter the background.

Some point after your application stops running, your Bonjour operations may be canceled.

In order for us to do very efficient and effective multitasking, the system is going to reclaim resources.

Not necessarily always but it does this so that the other applications that are in the foreground can actually get a much better experience.

The other thing it may do is reclaim the actual networking sockets.

Now, it's not actually going to close your sockets.

It's going to do something much more akin to a shutdown and you don't know it's happening, right.

Your application is not actually running right now.

You're not scheduled on the processor so you have no idea that this is going on and that this happened.

And again, it doesn't always happen.

This is when the system decides to reclaim some resources.

So at some point in the future here, your code is actually going to resume running.

But again, you don't really get any kind of notification this is happening.

You're just going to get scheduled again and your code's going to start running.

What's important to note here is this is when you should deal with the aftermath of these things happening, right.

This is where you need to be robust to errors on your networking sockets, errors in you Bonjour operations, all these things, because this may actually happen depending on scheduling before you get applicationWillEnterForeground.

Do not use applicationWillEnterForeground as a notification that you need to clean up your world.

Your world may be dirty before that because your application actually started running on the processor before you got this callback.

Now, in general you should be robust to network issues, right?

This is not just multitasking.

I can walk across the room and now I'm closer to this set of MiFis so my networking is going to be busted, right.

So just the usual walking around might have effects on networking.

So be robust to networking issues, right including things that happen when you get resumed after multitasking, after going in the background and coming back up.

So merely building with iOS 4 gets you this behavior, right?

Your application will go into the background, it will get suspended.

After a resume, all your Bonjour networking may be broken for your app.

You'll no longer be advertising anything.

You'll no longer be discovering anything.

Your network sockets might be closed.

Detect and fix that broken state or the user experience with your app is going to be worse than it was with iPhone OS 3.

This is very, very important, right?

There's no UI for users to go exit your app, at least no UI that they're really going to understand, right.

There's no Quit button.

There's nothing that says I want you to relaunch my app from scratch.

If your app doesn't clean up the first time it resumes, your app is going to be dead in the water.

When the user switches back to your app at anytime in the future, you don't want it to be host, right.

You want it to work again.

So be robust to these kinds of errors even if you're not getting a resume.

You might get networking errors for other reasons.

So if you're using the NSNetService or the CFNetService APIs, you'll get called back with an error code.

When you get callback with that error code, restart your Bonjour operations if that's where you are, if that's where you want your user to be.

Again, you shouldn't be browsing all the time.

You should be browsing or resolving when the user actually wants to because there are some power implications and things like that.

With the lower-level C APIs, if you're calling DNSServiceProcessResult yourself, check for the return code ServiceNotRunning and then restart your Bonjour operations.

If you're using the new SetDispatchQueue, it will call all your callbacks with ServiceNotRunning because again you're not calling DNSServiceProcessResult yourself.

You're letting all the cool dispatch stuff take care of that for you.

When you get ServiceNotRunning, restart all your Bonjour operations.

If you're using the low-level C APIs, we highly recommend that you use the new SetDispatchQueue API because it allows for us to do future improvements, right?

In the future, we could automatically start all the things back up for you and you will not even get errors when you resume.

And the last thing is you can actually opt out of this behavior by adding this thing to your info.plist.

And now back to Stuart.

[ Applause ]

Stuart Cheshire: Thank you Rory.

So, in other news we just released Bonjour for Windows 2.0.2 and this brings Bonjour on Windows to feature parity with Bonjour on Mac OS 10.6, Snow Leopard.

It's installed with iTunes on Windows, with Safari.

Now with Bonjour Print Services which lets Windows machines share printers on your Mac.

There's an SDK for developers which gives you additional tools and the header files, the documentation.

One of the key new things which you will be happy about if you're a Windows developer is we have the new shared connection mode.

And I'll talk in a minute about why that's useful.

We have some stuff code to do weak-linking.

I'll explain that.

And it also supports Sleep Proxy just like Snow Leopard.

You might ask why does Apple do Bonjour for Windows?

Well, we want a world where network products talk to each other effortlessly.

And a lot of you guys are making applications for the iPhone and a lot of those applications may want to synchronize data with information on the user's home computer.

And we don't want you to have to do one set of things for Macs and something different for Windows.

So, you can use the same network protocol, a very efficient, mature, robust service discovery protocol and have that available on Windows as well.

On Mac OS X, adding event source to your run loop is very easy and every Bonjour operation in the original API stands alone as its own event source.

The feedback we have from Windows programmers is that it's not so easy on Windows.

The way you typically program on Windows is you make the list of sources you're waiting for then you tell Windows to wait for something interesting to happen with one of those sources and then when it returns you process the events.

But having creating a new operation while you're waiting means you've got to break out of that loop and make a new list and go back into it.

And it's possible to do.

Many people have done it but it is extra work.

So, we have this new mode which is also available on Snow Leopard and iOS which is where you make a shared connection and then you can add new Bonjour operations to that one shared connection which means on application startup you make a single Windows events source, put that in your WaitForMultipleObjects list and then you don't have to keep adding and removing event sources.

The way that works is first you call createConnection on startup and then you copy that DNSServiceRef and do a new operation passing the shared connection flag.

You can make another copy of that service ref and start another operation.

Each operation can have a different callback function to handle the events or as in this case, they both have the same reply function but they have a different context pointer which is how the reply function knows which particular event has just happened relating to which operation.

Typically, this context pointer would be a pointer to your object or structure or something else defining the state of that operation you're doing.

I always like to show things at the developer conference which are not made by Apple because this is an open standard and I'm always interested to see what the other developers are doing with it.

RealVNC is now using Bonjour in their Windows and iPad products.

I am going to show you that.

Their server for Windows advertises with Bonjour and their client on the iPad uses Bonjour to discover servers.

RealVNC is using the weak-linking capability that I talked about.

On the Mac, since the day before OS X, we had this concept called weak-linking.

You could write an app that linked to some feature that was new in Mac OS 10.6 and if the user ran it on 10.5 they wouldn't get a DLL link error.

The application would still launch but its functions would be effectively like null function pointers.

And you as a developer could know that and check those functions were not null before you called them and that way your application would still run.

It just might miss some of the new functionality but it's not going to fail to launch.

It came as a surprise to us that Windows doesn't have that.

So, that means developers have to roll their own functionality and again this was feedback we heard from developers and in Bonjour for Windows 2.0, we do that for you.

We have helpers to help you link in your library and it does the DLL calls to see if Bonjour is installed and if it's not installed then when you call the function you get an error and so it uses that so you don't have to have Bonjour installed to use their server and if it's not installed, their server will try to advertise the service and get an error and it will continue and run correctly.

But if Bonjour is installed then the server will advertise with it.

So let's see if I can show you that now.

Okay, so, I have my machine here running Windows and I have my iPad.

I will this is the RealVNC VNCViewer and I can run this and this is the out of the box configuration.

Let's see what's available on the network.

And without typing in any configuration information, this has used Bonjour to find a couple of VNC servers it can talk to.

This version displays the IP address.

You wouldn't do that in a normal application but one thing you will notice here is those addresses say 169.254 and I'm pointing that out because I'm not connected to any of the network here.

This is just on my laptop here.

I created a wireless network and on the iPad I joined it.

There is no DXUP server.

This is a TCP/IP network with 2 devices on it.

They pick their own link local addresses, they use Multicast DNS.

They've discovered each other and this is a common developer mistake to say wait, I better use the reachability APIs and make sure I can talk to the internet and oh no, I can't.

I'm going to put up an error messages and refuse to work.

You don't need to talk to the great mainframe in the sky to do useful networking.

Quite often you may have a device that you just want to set up and VNC could be a great way of doing that and talking to that.

The reachability APIs are a great way to notify you.

If you try to connect and you fail, you can use reachability to get a notification about when the network environment has changed.

So it might be good time to try again.

But there are terrible preflight checks because they can only ever make things worse.

If you just try to connect you will either succeed or fail.

If you use reachability as a preflight check before that it can't ever make a failed connection succeed.

A connection that would have failed will still fail but it can make you not try in a case that would have succeeded.

So general lesson here and I highly recommend going to the sessions this afternoon at networking on iPhone OS, two parts.

They cover a lot of details about dealing with networking in a modern world, particularly networking on mobile devices.

I recommend those.

And let's see what happens when I connect to this.

And so, with zero-configuration I have just discovered and connected from an Apple iPad device to a Microsoft Windows machine and you saw how easy that was.

For any of you guys who've set up things like network cameras and tried to configure IP address and things.

You know it can be something that you planned half a Saturday afternoon for.

With Bonjour you just connect and it works, so let's move on.

[ Applause ]

So I have this is not a shipping product yet but I'm very excited.

Oh I'm sorry, I'm getting ahead.

So, you all know that the iPhone uses WebKit as its HTML rendering engine.

And I'm sure you know that Palm devices and Android phones use WebKit as well.

And you know that iPhone OS uses Bonjour for its service discovery.

Well I'm very happy to say that last month at Palm's developers conference they announced that Palm will also be supporting the Bonjour APIs and you can already get Android apps that use Bonjour by embedding a Java implementation of Bonjour but by the end of the year, I'm told that Android OS will have Bonjour APIs itself so that every app doesn't have to embed its own copy.

So, you could use the same HTML 5 on all these mobile platforms and you can use the same Bonjour service discovery on all these mobile platforms.

Now I'm sure many people in this room have probably experimented with the technology called X10.

For those of you who don't know, it's a power line signaling mechanism that's been around since the '70s, I think.

And the idea is great.

You can have a little module that you plug into the wall and you plug your table lamp into it.

And then you could have another device, a switch connected to the power lines that's not mechanically switching the power on and off.

It's sending signals over the power line to tell that module to turn the lights on or off or brighten or dim.

And this is a great idea for being more flexible about how you control things in your house.

But the protocol is slow and unreliable.

There's no acknowledgment.

There's no retransmission.

So, for a lot of people it's a very frustrating experience.

The promise is there but the reality doesn't really live up to it.

And time is long overdue I think for something that is like X10 but works a lot better.

These products and they are not on sale yet so I'm not going to give the company name but look for these in the shops by Christmas, I hope.

This is little module you plug in the power outlet and they have Wi-Fi in them and Bonjour and there's an iPhone app which uses Bonjour to discover all of these modules wirelessly, not over the power line over Wi-Fi.

And from the iPhone app you can tell it to turn on or off or brighten or dim but the difference because this is Wi-Fi is you don't press brighten 4 times and two of the packets got lost so you have to press a few more times to reach the right brightness.

That kind of worked when a human is doing it but when a computer is controlling things, it can't tell how bright the light is by looking at it so you really need something reliable.

So, you can send commands to the module to turn on and turn off and brighten and dim.

That circle on the front is actually a push button so you can override it.

So, if you don't want to dig out your phone you can press the button to turn it on and off.

And because it's all software controlled when you press that button, it can signal back to the app on your iPhone or your computer that the button was pushed which you can use as a trigger to turn other things on or off in the house.

These things also have a power meter in them.

Some of the people in this room have probably bought power meters because they are curious about how much power their television and their computer and their printer take.

Well, these have power metering built into them.

So you don't need a separate box with an LCD display.

Just on your iPhone screen, you can see the amount of power that's being consumed by each device plugged into these things and even chart it overtime to see the refrigerator compressor cycling on and off.

And you can use that as a trigger for events so that when you turn the television on it senses the increased power draw and sends messages to other modules to tell them to turn off the lights and turn on the amplifier and you can build all of these things that communicate with each other and automate things in your home over Wi-Fi using Bonjour.

So, the whole Bonjour team is very excited about this and we're going to be first in line to buy these as soon as they go on sale.

This was exactly the kind of thing that I hoped to see happen when we started the Bonjour effort ten years ago.

Bonjour is not just about desktop Macs and PCs, although it's certainly good that we make those easier to use but where it's critically important is devices like this where you can't hook up a screen and a keyboard to configure them.

They absolutely have to be bullet proof and self configuring and you can't afford the tech support costs of people calling up trying to work at how to configure them.

You have to just have them plug in and work.

So with that, I'll get to our tips and reminders.

You've heard this in other sessions and I'm going to repeat it here.

Make sure your applications work with IPv6.

IPv4 has link-local addressing but it was kind of an add-on after the fact to IPv4.

IPv6 has had it built-in from the start and the API supports it more elegantly.

So, we wholeheartedly recommend IPv6.

We use IPv6 in our own base stations, that's how you configure AirPort Express is with an IPv6 link-local address to communicate with it.

You'll hear this message in the iPhone networking sessions.

Networking is asynchronous.

Things don't always in the real world like they might work in your lab.

Here's one example.

If you do asynchronous blocking DNS call on your main thread and the DNS server happens to be not responsive for that user, the standard DNS time matches 30 seconds.

Well, your app will get jettisoned after 20 seconds if it's not responsive.

So, your app dies.

People say why don't you just make the timeout shorter?

But that really isn't the answer because even having your app unresponsive for 5 seconds is not a good user experience for the user.

And 5 seconds may not be long enough for a slow DNS server.

So, the answer is not synchronous blocking calls and trying to get the time out right.

The answer is to embrace the fact that networking is asynchronous.

Do things on a background thread or even better, do things in an event driven basis using CFRunLoop or using the new libdispatch Grand Central Scheduling.

Some that we see sometimes in Windows applications is a Refresh button and we don't want to see that in Bonjour applications on Mac or Windows and if you think about the iChat Bonjour Buddy List think about the sidebar on iTunes, think about the Safari Bonjour list, there's no Refresh button.

The list should always be fresh.

So, the Bonjour APIs make this very easy.

You start to browse you get out and remove events for the lifetime of that browse.

You don't have to have a timer the way you do when you browse every minute to see what's changed.

We've seen applications that do a browse for 10 seconds and then stop and then another one and then That's actually harder on the network than just leaving the browse running because the browse settles off to a low query rate and then just pays attention to the events on the network.

Generally, we recommend using the window so when the user wants to connect to a service you may have a UI today where there's a field where they type in the host name.

Well, you can still have that but next to that you can have a Bonjour button which brings up a browsing list.

And for the time that list is on the screen it should be live.

And then the user closes it and you stop the browse.

We prefer a window to a pull down menu because while the APIs exist from modifying a pull down menu while it's on the screen, it's disconcerting to use this.

They're not really used to pulling down a menu and seeing all the things jumble around and change.

So we recommend using a window not a pull down menu.

The way your client will discover instances of your service and not other services is that every service has a unique name.

You don't have to pay to register this.

Just go to dns-sd.org and make sure you register a unique identifier for your service.

We often see in the wild on networks like WWDC here, we look at the services that are being advertised and we always see a few that aren't on the service type list.

So, save yourself headaches by just going to that webpage, send the email, register your service type.

In the first version of Bonjour many years ago we had a domain parameter.

And it was there for future expansion but it wasn't used at the time.

Now, that we have wide area Bonjour and Back to My Mac, don't ignore the domain parameter.

When you do a browse you get back name, type, domain, and the interface index and you need to store all of those or at least name, type, and domain and pass those three unchanged to the resolve call.

We have seen bugs where people ignore the domain or they just hard code local and that works with local Bonjour but you're losing the benefits of Back to My Mac if you do that.

Don't ignore the port number.

Historically, networking has had the concept of well-known ports.

Port80 is the web server.

Well, you can only have one port80 on a machine.

So with fast user switching, if there's multiple application and multiple copies of the same application running they can't all have the same port number.

There are a lot of bits to software today that use a webpage as their configuration UI which is great but again, they can't all have port80.

When you've got multiple computers at home behind the NAT Gateway, they're all sharing one IP address.

There's only one port80 on that IP address.

So, we knew this was going to happen and that's why the Bonjour resolve call gives you back the port number.

When you create your service, you can specify 0 when you bind and the kernel will pick an unused port for you.

The register API has a parameter for you to say what port number you're listening on and that goes into the network packets and the resolve call will tell the clients we have seen applications.

They do the resolve.

They get back the address in the port.

They ignore the port and try to connect to the well-known ports and that only works if you get lucky.

The first copy of the application may get the port at once but all the others won't.

So, this creates situations with Back to My Mac or with other wide area Bonjour things where you can only connect to one thing at the group but the other ones that aren't on the standard port don't work when they connect to the wrong thing.

For your marketing materials and your packaging and your webpages, if you use Bonjour then you can license the Bonjour logo for no cost just like the Made for iPhone and Made for iPad logos to let your customers know that they can expect a painless, trouble-fee experience with your products.

If you're using the Bonjour APIs on Mac and Windows then you are good to go.

If you are building pieces of hardware which we love to see then we have a Bonjour conformance test which you can run to help you find bugs in your implementation and if you pass that test then you can also use the Bonjour logo on your packaging.

And I encourage you to run that test because it does help you find bugs that might cause trouble for customers in the field.

If you are doing something where you want a component that runs on Windows you can license Bonjour for Windows and that is also free with iTunes being on so many machines.

There are a hundred million copies of Bonjour for Windows already out there so you may not even have to install it but if you want to include that with your software you can license that for no fee.

Safari on Windows has the same Bonjour browsing that Safari on Mac OS X does.

So to wrap up, especially with things like peer-to-peer over Bluetooth on the phone, having an app that's constantly browsing all the time in the background has a toll in battery life.

So, when the user hits the button to bring up your browsing list you start the browse and then leave the browse live so they're getting live information but when the user dismisses, it stops.

That's what we recommend.

We know that not all apps from Apple set the best example here.

iTunes has the sidebar that's browsing all the time but particularly on the phone, we recommend browsing when the user is actually actively looking for stuff but otherwise, don't be browsing all the time.

And in the same vein, don't resolve everything you find because that could be very expensive.

You're triggering a whole bunch of mechanism by resolving there that you really don't need to trigger until you're actually ready to make a connection.

Embrace the fact that networking is asynchronous.

It can seem like a pain if you're used to non-network programming where the computer is in charge where you say do this and then do this and then do this and you'll write nice sequential programs the way we all learn to program.

But networking like graphical user interfaces is one area where you are not in charge.

In GUIs, the user is deciding what button to click next and in networking, the environment around you is deciding what's going to happen next.

And fighting against that is really unproductive.

Pay attention to the multitasking issues that Rory told you about.

You have to pay attention to the network sockets being broken because otherwise when your app resumes, it may not work and with no easy way for the user to quit it, we don't want to be in a situation where users end up rebooting their phone because they don't know how to fix the broken apps and use the Bonjour logo.

This is the contact information for our technology evangelists.

We have documentation on the webpage.

In the interest of full disclosure, I was co-author on this book.

This is the O'Reilly Zero Configuration Networking book which is a I'd like to say it's a more cohesive form of documentation in the sense that you can read it safely in the bathtub.

Later today we have the iPhone OS networking sessions which I highly recommend, the Core OS Networking overview, you can watch on video and the Multitasking on iPhone OS is going to be repeated on Friday.

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US