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

Configurable publish service announcement #48

Open
miqmago opened this issue Jun 18, 2018 · 1 comment
Open

Configurable publish service announcement #48

miqmago opened this issue Jun 18, 2018 · 1 comment

Comments

@miqmago
Copy link

miqmago commented Jun 18, 2018

I would like to have a raspberry pi with a service announced in a continuous way, in that way an app could detect the service and start operating with it.

Digging inside registry.js I've seen that the delay is autocalculated with fixed constants: REANNOUNCE_FACTOR and REANNOUNCE_MAX_MS (https://github.com/watson/bonjour/blob/master/lib/registry.js#L147)

I suggest to make it configurable via publish options. Does it make sense?

I think I could implement this feature and I'm open for pull requests, are they welcome?

My proposal would be to pass those parameters via publish opts and then fetch them inside registry.js.

Something like this:

Registry.prototype.publish = function (opts) {
  var service = new Service(opts)
  service.start = start.bind(service, this)
  service.stop = stop.bind(service, this)
  service.start({
    probe: opts.probe !== false,
    reannounceFactor: opts.reannounceFactor || REANNOUNCE_FACTOR,
    reannounceMaxMs: opts.reannounceFactor || REANNOUNCE_MAX_MS
  })
  return service
}


function start (registry, opts) {
  if (this._activated) return
  this._activated = true

  registry._services.push(this)

  if (opts.probe) {
    var service = this
    probe(registry._server.mdns, this, function (exists) {
      if (exists) {
        service.stop()
        service.emit('error', new Error('Service name is already in use on the network'))
        return
      }
      announce(registry._server, service, opts)
    })
  } else {
    announce(registry._server, this, opts)
  }
}


function announce (server, service, opts) {
  var delay = 1000
  var packet = service._records()

  server.register(packet)

  ;(function broadcast () {
    // abort if the service have or is being stopped in the meantime
    if (!service._activated || service._destroyed) return

    server.mdns.respond(packet, function () {
      // This function will optionally be called with an error object. We'll
      // just silently ignore it and retry as we normally would
      if (!service.published) {
        service._activated = true
        service.published = true
        service.emit('up')
      }
      delay = delay * opts.reannounceFactor
      if (delay < opts.reannounceMaxMs && !service._destroyed) {
        setTimeout(broadcast, delay).unref()
      }
    })
  })()
}
@tonyg
Copy link

tonyg commented Dec 11, 2018

The current implementation announces each service record on a fixed schedule, but doesn't respond at all to incoming query packets. Rather than alter the schedule to produce unsolicited announcements more regularly, could it work for you to add handlers in registry.js that responded to query events? The RFC describes the approach. Responding to incoming queries would likely reduce latency and increase reliability of service discovery in your setting without increasing traffic caused by unsolicited announcements.

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

2 participants