diff --git a/README.md b/README.md index b0daaa2..792a5ef 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,10 @@ Options are the same as given in the `browser.find` function. Emitted every time a new service is found that matches the browser. +#### `Event: update` + +Emitted every time an update is received for existing service is found that matches the browser. + #### `Event: down` Emitted every time an existing service emmits a goodbye message. @@ -136,7 +140,7 @@ Broadcast the query again. #### `Event: up` -Emitted when the service is up. +Emitted when the service is up, and if the txt record of the service is updated `service.updateTxt(object)`. #### `Event: error` diff --git a/lib/Browser.js b/lib/Browser.js index 6ad49d7..f8d5f98 100644 --- a/lib/Browser.js +++ b/lib/Browser.js @@ -82,8 +82,11 @@ Browser.prototype.start = function () { if (matches.length === 0) return matches.forEach(function (service) { - if (self._serviceMap[service.fqdn]) return // ignore already registered services - self._addService(service) + if (self._serviceMap[service.fqdn]) { + self._updateService(service) + } else { + self._addService(service) + } }) }) } @@ -109,6 +112,21 @@ Browser.prototype._addService = function (service) { this.emit('up', service) } +Browser.prototype._updateService = function (service) { + let cachedService, index + this.services.some(function (s, i) { + if (dnsEqual(s.fqdn, service.fqdn)) { + cachedService = s + index = i + return true + } + return false + }) + if (!cachedService) return + this.services[index] = service + this.emit('update', service) +} + Browser.prototype._removeService = function (fqdn) { let service, index this.services.some(function (s, i) { diff --git a/test/bonjour.js b/test/bonjour.js index 1bb3691..c1ffa12 100644 --- a/test/bonjour.js +++ b/test/bonjour.js @@ -118,32 +118,58 @@ test('bonjour.find', function (bonjour, t) { bonjour.publish({ name: 'Baz', type: 'test', port: 3000, txt: { foo: 'bar' } }).on('up', next()) }) -test('bonjour.change', function (bonjour, t) { - const data = { init: true, found: false, timer: null } - const service = bonjour.publish({ name: 'Baz', type: 'test', port: 3000, txt: { foo: 'bar' } }).on('up', function () { - const browser = bonjour.find({ type: 'test' }) - browser.on('up', function (s) { - data.browserData = s +test('bonjour.change and up event', function (bonjour, t) { + const data = { updateTxtSent: false, found: false, timer: null, serviceUp: false } + data.timer = setTimeout(function () { + t.equal(data.found, true) + bonjour.destroy() + t.end() + }, 3000) // Wait 3000 ms for any additional up messages when the updateTxt is sent + const service = bonjour.publish({ name: 'Baz', type: 'test', port: 3000, txt: { foo: 'originalUp' } }).on('up', function () { + if (!data.serviceUp) { // Workaround for Service.up firing when service.updateTxt is used + data.serviceUp = true + const browser = bonjour.find({ type: 'test' }) + browser.on('up', function (s) { + t.equal(s.txt.foo, 'originalUp') + data.found = true + if (!data.updateTxtSent) { + data.updateTxtSent = true + service.updateTxt({ foo: 'updateUp' }) + } + }) + } + }) +}) + +test('bonjour.change and update event', function (bonjour, t) { + const data = { updateTxtSent: false, success: false, timer: null, serviceUp: false } + data.timer = setTimeout(function () { + t.equal(data.success, true) + bonjour.destroy() + t.end() + }, 3000) // Wait for the record to update maximum 3000 ms + const service = bonjour.publish({ name: 'Baz', type: 'test', port: 3000, txt: { foo: 'original' } }).on('up', function () { + if (!data.serviceUp) { // Workaround for Service.up firing when service.updateTxt is used + data.serviceUp = true + const browser = bonjour.find({ type: 'test' }) + browser.on('up', function (s) { + t.equal(s.txt.foo, 'original') + if (!data.updateTxtSent) { + data.updateTxtSent = true + service.updateTxt({ foo: 'update' }) + } + }) - if (data.init) { - t.equal(s.txt.foo, 'bar') - data.timer = setTimeout(function () { - t.equal(s.txt.foo, 'baz') + browser.on('update', function (s) { + if (s.txt.foo === 'update') { // Ignore updates that we are not interested in, have seen updates of just address information + t.equal(s.txt.foo, 'update') + data.success = true + clearTimeout(data.timer) bonjour.destroy() t.end() - }, 3000) // Wait for the record to update maximum 3000 ms - data.init = false - service.updateTxt({ foo: 'baz' }) - } - - if (!data.init && !data.found && s.txt.foo === 'baz') { - data.found = true - clearTimeout(data.timer) - t.equal(s.txt.foo, 'baz') - bonjour.destroy() - t.end() - } - }) + } + }) + } }) })