jdomnitz / net-mdns

Simple Multicast DNS (MDNS) Client/Server
MIT License
22 stars 6 forks source link

Simple forms app using quick start boiler plate code not seeing mDNS Advertisements #32

Closed exedor closed 3 months ago

exedor commented 3 months ago

I threw together a couple of .NET8 C# desktop winforms projects. The server is a simple form with 2 buttons. The ServiceDiscovery object is created in the constructor. One button problems for service conflicts and if there are none, Advertises. A second button manually sends another Advertisement.

Here's the server code: ` public partial class DiscoveryServer : Form { private readonly ServiceProfile _svcProfile; private readonly ServiceDiscovery _svcDiscovery;

    public DiscoveryServer()
    {
        InitializeComponent();

        _svcProfile = new("x", "_foo._tcp", 9780);
        _svcDiscovery = new();
    }

    private void BtnListen_Click(object sender, EventArgs e)
    {
        if (_svcDiscovery.Probe(_svcProfile))
            Debug.WriteLine("service conflict found!");
        else
            _svcDiscovery.Advertise(_svcProfile);
    }

    private void BtnAdvertise_Click(object sender, EventArgs e)
    {
        _svcDiscovery.Advertise(_svcProfile);
    }
}

`

The client can see other services advertising, but can never see the _foo._tcp service. Both client and server projects are part of the same solution. They both start at the same time and run on the same system.

Here's the client code: ` public partial class DiscoveryClient : Form { private readonly ServiceDiscovery sd;

    public DiscoveryClient()
    {
        InitializeComponent();
        sd = new ServiceDiscovery();
    }

    private void BtnDiscover_Click(object sender, EventArgs e)
    {
        Debug.WriteLine("Discovering all services on the local link...");

        sd.ServiceDiscovered += (s, serviceName) =>
        {
            Debug.WriteLine("Service: " + serviceName + " discovered");
        };

        sd.ServiceInstanceDiscovered += (s, e) =>
        {
            Debug.WriteLine("Service instance discovered!");
        };
    }
}

`

I see the joins happen from the Reference count show in the command: netsh int ip show joins

I would expect to see some Debug output from the client anytime the server advertises, but it never gets anything. I've disabled all firewalls, malware scanners, and anything else I could think of that might possibly be intercepting and/or interfering with the traffic.

exedor commented 3 months ago

OK, I downloaded Wireshark and am now taking local packet traces. The Advertise call, does not seem to do anything at all, which would explain why the client isn't seeing anything.

jdomnitz commented 3 months ago

Try setting IncludeLoopbackInterfaces on MulticastService and see if that helps.

Advertise shouldn't be doing anything external. It's listening for a query from the client that it isn't getting. You can try Announce to manually send a response if that's helpful for testing.

exedor commented 3 months ago

Thank you for responding. Yeah, I realized after more research that I was expecting advertise to actually "advertise" so PEBCAK error on my part. It's been over a decade since I've worked with multicast. I caught onto announce and have been working with that. It seems to result in a ServiceInstanceDiscovered event on the client, which is fine and I can work with that. Although, I do see the ServiceDiscovered event get triggered for other things, e.g. _nvstream_dbd._tcp.local. What on the server would be called for awareness of the service, i.e. ServiceDiscovered event to happen without any actual instances of that service?

jdomnitz commented 3 months ago

Although, I do see the ServiceDiscovered event get triggered for other things, e.g. _nvstream_dbd._tcp.local. What on the server would be called for awareness of the service, i.e. ServiceDiscovered event to happen without any actual instances of that service?

That's likely the OS on the server responding with locally registered services. That one in particular is NVidia Gamestream server.

exedor commented 3 months ago

I think I see now. ServiceDiscovered happens when a different response is being sent to a prior query and the client sees it.

jdomnitz commented 3 months ago

Give the current version a try and see if that helps your issue. That should allow your server to see the clients query instead of requiring Announce to be called.

exedor commented 3 months ago

Thank you! I'm using the nuget package. Will that get updated from here or do I need to switch away from nuget for this?

jdomnitz commented 3 months ago

nuget package is now published as version 0.32. It may take a few hours to propagate depending on where you pull packages from.

exedor commented 3 months ago

Thank you! This is working much better and more consistently with what I might expect. Although, interestingly, on the client ServiceInstanceDiscovered now gets fired twice on each Announce from the server, about 1 second between each of them. Is that intentional or part of the specification?

jdomnitz commented 3 months ago

That is by design. Section 8.3 of the specification: The Multicast DNS responder MUST send at least two unsolicited responses, one second apart. To provide increased robustness against packet loss, a responder MAY send up to eight unsolicited responses, provided that the interval between unsolicited responses increases by at least a factor of two with every response sent.

exedor commented 3 months ago

I appreciate the reference, but I'd have believed you if you just yep, part of the spec! ;) Many thanks for the fix and your time and effort in maintaining this package.