Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent discovery #35

Open
matthewtmoran opened this issue Jul 18, 2017 · 14 comments
Open

Inconsistent discovery #35

matthewtmoran opened this issue Jul 18, 2017 · 14 comments

Comments

@matthewtmoran
Copy link

As with many of the unresolved discovery issues, I as well am experiencing issues discovering services across different devices. This is consistent with windows and mac. I'm able to publish services from each device and discover each devices' service, however once the process is restarted, the 'up' event listener is not triggered again (or at least not consistently).

Anyone have a solution of any kind, or point me in the direction of another package with similar functionality?

@dsamarin
Copy link

Can you correlate the event callbacks with datagrams sent with something like Wireshark? The problem could be in either the publisher or finder. Can't reproduce here.

@thosil
Copy link

thosil commented Aug 17, 2017

I have a third party service that do not unpublish when going down (there's no "down" event), when it's up again, bonjour.js do not trigger an "up" event.
Is there a way to have a "keep-alive" mechanism within bonjour? or explicitly tell the browser that a service has vanished?

@matthewtmoran is it the same thing you're experiencing?

@matthewtmoran
Copy link
Author

@thosil That does seem to be what I was experiencing. It's been a while since a looked at in depth as I've moved onto another module to accomplish what I need. I do recall that Bonjour would work as it should the first time I'd run it but then I'd have to restart my pc for it to work properly again.

@betamos
Copy link

betamos commented Dec 18, 2017

It's pretty easy to reproduce:

  1. On both my Debian and OS X machine, I both publish() and find() the same service type, with default options, over local Wifi network.
  2. I disconnect the OS X machine from the network, and then reconnected a couple of minutes later.

No new up event is triggered on the Debian machine. Even if I restart the process on the OS X machine entirely – forcefully causing a fresh publish – the Debian machine doesn't pick it up, unless I restart its process as well.

Is it the nature of Bonjour itself or are any parameters (TTL?) configurable within the Bonjour protocol? In its current form, auxiliary data structures with custom life times are required to use these events as timely and reliable service discovery of devices that pop in and out of a network.

@thosil
Copy link

thosil commented Dec 18, 2017 via email

@betamos
Copy link

betamos commented Dec 18, 2017 via email

@mateo-io
Copy link

I'm having this problem of consistency as well in Windows 10.

Whereas on MacOS the service is immediately discovered.

@billhinkle
Copy link

The Browser's service map (for .find and .findOne) is a little overenthusiastic about rejecting incoming service announcements as "already known, hence ignored", and it also doesn't implement TTL-based re-inquiry. The mDNS RFC 6762 section 10.2 [https://tools.ietf.org/html/rfc6762#section-10.2] defines how continuous monitoring should be handled, to allow client notification on changes in service host info (ip, port, txt) by signaling with the cache-flush bit on the response record's class field. This does get bubbled up into the browser.js buildServicesFor function as a .flush flag, so that and the response record's TTL as .ttl can both be easily added to the service description object there (n.b. no relation to the packet's TTL). The Browser can then do a pretty simple-minded check on the service.flush flag and decide whether to update an existing service record instead of silently ignoring an apparent 'known' duplicate. If updated, either a new updated event could be emitted or add an isUpdate parameter to the callback on the existing up event. The client would have to determine what, if anything, was changed but at least it would get some notification. (That's nothing like the full timer-based cache-flushing scheme of the RFC's 10.2, but it seems to take care of a number of use cases I've run up against). With the .ttl available in the service descriptor, the re-inquire-when-approaching-service-ttl scheme could be implemented too, which would take care of a number of other situations. btw, 8.4 of that RFC says that unique service hosts with just rdata changes shouldn't send a goodbye at all, since the cache-flush is supposed to handle that function.
On an unrelated note, I've been a little suspicious that occasionally initial discoveries might be lost due to a race in .findOne wherein the up listener isn't registered before the query goes out from the new Browser. If it so happens that a response hits before that .once starts listening for up, the service will be mapped as 'known' and subsequently ignored, so that the first up is never 'heard' at all by that not-yet-set listener, and then never triggered for that service initially or thereafter. So .findOne would sit there sadly forever, in that case. Don't know if that's a realistic scenario, but for belt-and-suspenders .findOne should probably pass an onup callback directly to the Browser constructor, as does .find, and leave the current .once as is to handle the shutdown on first discovery. Within the Browser constructor, the passed parameter onup is set as an up listener before the service query goes out, so no chance of that particular race. (Also, I wonder if that .once up listener is being removed at some point in the current code?)

@ndamnjanovic
Copy link

@matthewtmoran hey Matthew, can you please tell me what is the other package that you're mentioning. I'm experiencing problems with this one, and I would like to try different solutions.

@matthewtmoran
Copy link
Author

@ndamnjanovic I can't remember exactly what package I ended up going with for my specific use case. I believe it was either multicast-dns or udp-discovery.

@ndamnjanovic
Copy link

@ndamnjanovic I can't remember exactly what package I ended up going with for my specific use case. I believe it was either multicast-dns or udp-discovery.

I'll check it, thanks for the prompt reply :)

@MrHarmony
Copy link

I worked around this issue, by keeping my own list of services of interest and an own mechanism of detecting wether the desired service(s) are/is still responsive (for instance by pinging them). When I detect they are down, I delete them from my own list and create a fresh browser instance. Now, if a once already detected service goes back online, the "up" event will be triggered again. And since I compare all detected services to my own list of services, every services that was still there before reinitiating the browser won't trigger anything inside my code unless I want to.
A bit of a hassle, yes, but at least it works.

@sistemicorp
Copy link

@MrHarmony I tried doing what you did, but I wasn't able to get success. I am using this in an Electron app. When the App starts, it is able to find the service. When I try and restart the search, I do not get any "up" events.

Startup:

const { Bonjour } = require('bonjour-service')
var bonjour = new Bonjour()
var browser = bonjour.find({ type: 'myserv' })

On Restarting (via a Menu event):

    delete bonjour;
    delete browser;
    bonjour = new Bonjour();
    browser = bonjour.find({ type: 'myserv' });
    browser.start();
    browser.update();

Ideally, browser.update(); would restart the scan.

Caveat: I am new to javascript.

@thomaspsik
Copy link

I changed parts of the browser implementation to be able to list services that are running on a different device.

I have no clue what to do with those changes. I can share my modifications here.
browser-modified.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants