Matt Thomas
Matt Thomas

Reputation: 5804

Advertise with `ServiceDiscovery.Dnssd`, discover with Bonjour?

Does the Windows.Networking.ServiceDiscovery.Dnssd namespace allow advertising a service that is discoverable through Apple's Bonjour?

Microsoft's documentation mentions all the right DNS-SD RFCs, but I can't discover my program using this Bonjour Browser program. I know that the Bonjour Browser program is working because it discovers other devices on my network as well as local services advertised through mDNSResponder. And Microsoft's documentation on this namespace is sufficiently vague to leave me wondering.

Does anything obviously wrong stand out in this code?

async Task RegisterServiceAsync()
{
    var hostNames = NetworkInformation
        .GetHostNames()
        .Where(x => x.Type == HostNameType.DomainName)
        .Select(x => new KeyValuePair<string, HostName>(x.ToString(), x))
        .ToList();
    var hostName = Pick("Pick a host name:", hostNames);
    Console.WriteLine($"Host name is \"{hostName}\"");

    var service = new DnssdServiceInstance(
        dnssdServiceInstanceName: "abc._tcp.local.",
        hostName: hostName,
        port: 13337
    );
    using (var socket = new StreamSocketListener())
    {
        var registration = await service.RegisterStreamSocketListenerAsync(socket);
        Console.WriteLine(registration.Status);
        Console.WriteLine($"Renamed: {registration.HasInstanceNameChanged}");
        Console.WriteLine($"Service instance name: {service.DnssdServiceInstanceName}");
        Console.ReadKey(true);
    }
}

Example output:

        1) hostname.domain.local
        2) hostname.local
Pick a host name: (1-2) 2
Host name is "hostname.local"
Success
Renamed: False
Service instance name: abc._tcp.local.

Upvotes: 0

Views: 1567

Answers (1)

Matt Thomas
Matt Thomas

Reputation: 5804

The dnssdServiceInstanceName was in the wrong format. It needs to be <<instance name>>._<<service name>>._<<protocol>>.<<domain>>.. For example, this code works:

async Task RegisterServiceAsync()
{
    var hostNames = NetworkInformation
        .GetHostNames()
        .Where(x => x.Type == HostNameType.DomainName)
        .Select(x => new KeyValuePair<string, HostName>(x.ToString(), x))
        .ToList();
    var hostName = Pick("Pick a host name:", hostNames);
    Console.WriteLine($"Host name is \"{hostName}\"");

    var service = new DnssdServiceInstance(
        dnssdServiceInstanceName: "instanceName._abcservice._tcp.local.",
        hostName: hostName,
        port: 13337
    );
    using (var socket = new StreamSocketListener())
    {
        var registration = await service.RegisterStreamSocketListenerAsync(socket);
        Console.WriteLine(registration.Status);
        Console.WriteLine($"Renamed: {registration.HasInstanceNameChanged}");
        Console.WriteLine($"Service instance name: {service.DnssdServiceInstanceName}");
        Console.ReadKey(true);
    }
}

I figured this out using this line of a Microsoft example program.

Upvotes: 1

Related Questions