ROZeroConf

ROZeroConf is an infrastructure for service discovery that is being added to Remoting SDK. It first shipped in the Summer 2009 releases, for all three editions of Remoting SDK.

ROZeroConf is based on open standards and also know under the names of DNS-SD (DNS Service Discovery) and Bonjour, and is available on all supported platforms, including Windows, Linux and Xcode.

Basic Functionality

ROZeroConf provides two major features:

  • automated discovery of services on the local network without the need of any central infrastructure or discovery service. Simply by running, ROZeroConf enabled services will be discoverable by clients.

  • registration and discovery of services globally across the internet with minimal configuration and a properly set up DNS server.

How ZeroConf Works

In ZeroConf, service providers (concrete instances of a service) are discovered based on two identifiers: a service type and a service name.

As the name indicates, the service type is used to uniquely identify the specific type of service, with the idea that services of the same type can be interacted with in the same manner. In Remoting SDK terminology, this would mean that a service type represents a specific service interface (or possibly group of interfaces) you have defined in your RODL.

All service type names follow the schema _'name'._tcp., and some predefined (non-RO) types would include _http._tcp. for HTTP or _ipp._tcp. for network printers. Remoting SDK extends this to _'name'_rosdk._tcp. for all services registered through it's ZeroConf support, to make them easier to distinguish, and avoid name conflicts.

The service name is used to identify the individual instance of a service that is running somewhere on the network. In most cases (and by default), this will be the host name of the computer running the server, but it is possible (and depending on the use case might be sensible) to override this from code, so your application can give administrators the option to choose a name.

The basic idea is that a client application would be capable to talk to any service of a given service type, and distinguish between different available choices, using the service name.

For example, you might be deploying three servers offering access to a certain service you are providing, running on servers server1 and server2. Clients could browse for the well-known service type on the network. If these services are advertised through ZeroConf with a custom-defined _MyCoSampleService_rosdk._tcp. service type, client applications could then browse for this type and automatically discover both server1 and server2. Whats more, as new servers go online, or existing servers are shut down, clients will automatically learn about the changes and can adapt, for example my connecting to a new server.

Requirements

Because ZeroConf allows seamless discovery of not just Remoting SDK servers but also other services, it uses a central service running on each machine that coordinates the publication and discovery of services across the network. This service is available by default on Mac OS X (as Bonjour) and most newer Linux distributions (as Avahi), but needs to be installed manually on Windows machines.

The preferred option is Bonjour for Windows, which is available and distributable free of charge from Apple at Bonjour for Windows . Apple's Bonjour implementation is based on open source DNS-SD implementations, and if you do not wish to deploy Bonjour, you can build your own version from the source available at http://bonjour.macosforge.org/. Bonjour for Windows might already be installed on many systems, for example as part of a network printer installation, or iTunes.

Making Your Services Discoverable

Allowing your services to be discovered requires only two very small changes to your server application.

Net: In your .NET servers, the following changes are necessary:

  • drop a ZeroConfRegistration component onto your form, and connect it to your ServerChannel component. (if you are using multiple channels, only one channel can be used for ZeroConf discovery)

  • add a [ZeroConfServiceType("YourServiceTypeName")] attribute to your service implementation.

This is all that's needed, and after you rebuild and run your service, it will be discoverable on the local network, provided Bonjour is installed. (As you will see below, a bit central configuration is needed to allow global discovery outside the LAN).

Delphi: In your Delphi servers, the following changes are necessary:

  • drop a TROZeroConfRegistration component onto your form, and connect it to your ServerChannel component. (if you are using multiple channels, only one channel can be used for ZeroConf discovery).

  • add following code into the initialization section of your service implementation or uncomment existing line.

RegisterForZeroConf(fClassFactory,'YourServiceTypeName');

Note that because services are published for a specific host and port, you can only publish one server channel, even if your server might be making its services available through several channels at the same time. We suggest to use your preferred or most optimal channel for discovery. Also note that if the service type you specify does not adhere to the naming scheme described above, Remoting SDK will automatically pre-pend an underscore and append _rosdk._tcp. as needed, so you do not need to worry about this and can provide a "simple" name.

Discovering Available Services

Net:

In your .NET clients, the following changes are necessary:

  • drop a ZeroConfBrowser component onto your form and setup its Domain property (set it to local. for LAN). Also set Type property to full name of service you will browse for (i.e. _bonjourdiscoverableservice_rosdk._tcp )
  • add event handlers for events ServiceAdded and ServiceRemoved to handle appearing/disappearing services respectively:
private void ZeroConfBrowser_ServiceAdded(object sender, ZeroConfBrowseResultArgs args)
{
  ZeroConfService service = args.Record;
  if (service.TryResolve())
    //Some actions here to handle information about newly appeared service
    LogMessage(String.Format("Added service: {0} at port {1}", args.Record.Name, args.Record.Port));
}

private void ZeroConfBrowser_ServiceRemoved(object sender, ZeroConfBrowseResultArgs args)
{
  ZeroConfService service = args.Record;
  //Some actions here to handle information about disappeared service
  LogMessage(String.Format("Service has gone down: {0} (at host {1}:{2})", service.HostTarget, service.HostTarget, service.Port));
}
  • to start receiving information about registered / unregistered services set ZeroConfBrowser's property Active to true

Delphi: In your Delphi clients, the following changes are necessary:

  • drop a TROZeroConfBrowser component onto your form and setup its Domain property (set it to local. for LAN) . Also set ServiceType property to full name of service you will browse for (i.e. _bonjourdiscoverableservice_rosdk._tcp )
  • add event handlers for events OnServiceAdded and OnServiceRemoved to handle appearing/disappearing services respectively:
procedure TClientForm.ROZeroConfBrowserServiceAdded(
  Sender: TROZeroConfBrowser; aRecord: TROZeroConfService);
var
    host: string
begin
  if  aRecord.TryResolve  then  begin
//Some actions here to handle information about newly appeared service
    host := StringReplace(aRecord.HostTarget, LOCAL_SUFFIX, '', [rfIgnoreCase]);
    LogMessage(Format('Service resolved. Host name: %s Port number: %d', [host, aRecord.Port]));
  end;
end;

procedure TClientForm.ROZeroConfBrowserServiceRemoved(
  Sender: TROZeroConfBrowser; aRecord: TROZeroConfService);
begin
  //Some actionshere to handle information about disappeared service
  LogMessage(Format('Service has gone down: %s (at host %s:%d)',
                            [aRecord.ServiceName,
                             aRecord.HostTarget,
                             aRecord.Port]));
end;
  • to start receiving information about registered / unregistered services set TROZeroConfBrowser's property Active to true.

Note that there are BonjourDiscovery sample where you can look at ZeroConf in action (shipped with Remoting SDK for .NET, Remoting SDK for Xcode and Remoting SDK for Delphi).