Open matthewtmoran opened 7 years ago
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.
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?
@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.
It's pretty easy to reproduce:
publish()
and find()
the same service type, with default options, over local Wifi network.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.
If your service shut down without unpublishing and then restart, the service won't be discovered again, because it was still known by Bonjour. If you really want to know if your service is still up, you have to implement a keep-alive feature in your app, but afaik that's not part of Bonjour.
Thanks for clarifying. Are you saying that if a service is not unpublished correctly it will stay around forever on the other node? Will there not be a down event emitted at any point? From looking quickly at the bonjour spec, there seems to be mentions of TTL.
On Sun, Dec 17, 2017 at 10:29 PM Thomas Silvestre notifications@github.com wrote:
If your service shut down without unpublishing and then restart, the service won't be discovered again, because it was still known by Bonjour. If you really want to know if your service is still up, you have to implement a keep-alive feature in your app, but afaik that's not part of Bonjour.
Le lun. 18 déc. 2017 à 05:39, Didrik Nordström notifications@github.com a écrit :
It's pretty easy to reproduce:
- On both my Debian and OS X machine, I both publish() and find() the same service type, with default options, over local Wifi network.
- 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.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/watson/bonjour/issues/35#issuecomment-352324358, or mute the thread < https://github.com/notifications/unsubscribe-auth/ABFnXuHFD5zBOfyePn7Jcjyb4pmoOlzkks5tBeydgaJpZM4Obc5D
.
--
SILVESTRE Thomas
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/watson/bonjour/issues/35#issuecomment-352337181, or mute the thread https://github.com/notifications/unsubscribe-auth/AAITGIiNSu_iuxP6BIymO97voHLXv2g1ks5tBgYrgaJpZM4Obc5D .
I'm having this problem of consistency as well in Windows 10.
Whereas on MacOS the service is immediately discovered.
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?)
@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.
@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 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 :)
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.
@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.
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
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?