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

Added support for subtypes #5

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ var EventEmitter = require('events').EventEmitter
var serviceName = require('multicast-dns-service-types')
var txt = require('mdns-txt')()

var TLD = '.local'

module.exports = Browser

util.inherits(Browser, EventEmitter)
Expand All @@ -30,7 +28,12 @@ function Browser (mdns, opts, onup) {

if (onup) this.on('up', onup)

this._name = serviceName.stringify(opts.type, opts.protocol || 'tcp') + TLD
this._type = opts.type
this._name = serviceName.stringify({
name: opts.type,
protocol: opts.protocol || 'tcp',
subtypes: opts.subtypes
})
this._mdns = mdns
this._onresponse = null
this._serviceMap = {}
Expand All @@ -46,7 +49,7 @@ Browser.prototype.start = function () {
this._onresponse = function (packet) {
goodbyes(self._name, packet).forEach(self._removeService.bind(self))

var matches = buildServicesFor(self._name, packet)
var matches = buildServicesFor(self, packet)
if (matches.length === 0) return

matches.forEach(function (service) {
Expand Down Expand Up @@ -97,14 +100,26 @@ function goodbyes (name, packet) {
})
}

function buildServicesFor (name, packet) {
function buildServicesFor (browser, packet) {
var records = packet.answers.concat(packet.additionals).filter(function (rr) {
return rr.ttl > 0 // ignore goodbye messages
})

return records
.filter(function (rr) {
return rr.name === name && rr.type === 'PTR'
// check the type
if (rr.type !== 'PTR') {
return false
}

// Check for matching type
var sn = serviceName.parse(rr.name)
if (sn.name !== browser._type) {
return false
}

// No match
return true
})
.map(function (ptr) {
var service = {
Expand All @@ -119,14 +134,14 @@ function buildServicesFor (name, packet) {
if (rr.type === 'SRV') {
var parts = rr.name.split('.')
var name = parts[0]
var types = serviceName.parse(parts.slice(1, -1).join('.'))
var types = serviceName.parse(parts.join('.'))
service.name = name
service.fqdn = rr.name
service.host = rr.data.target
service.port = rr.data.port
service.type = types.name
service.protocol = types.protocol
service.subtypes = types.subtypes
service.subtypes = types.subtypes || []
} else if (rr.type === 'TXT') {
service.rawTxt = rr.data
service.txt = txt.decode(rr.data)
Expand Down
2 changes: 0 additions & 2 deletions lib/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ function announce (server, service) {
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
Expand Down
31 changes: 23 additions & 8 deletions lib/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ var EventEmitter = require('events').EventEmitter
var serviceName = require('multicast-dns-service-types')
var txt = require('mdns-txt')()

var TLD = '.local'

module.exports = Service

util.inherits(Service, EventEmitter)
Expand All @@ -19,11 +17,24 @@ function Service (opts) {

this.name = opts.name
this.protocol = opts.protocol || 'tcp'
this.type = serviceName.stringify(opts.type, this.protocol)
this.type = opts.type || 'http'
this.host = opts.host || os.hostname()

// Sometimes the os reported hostname has the parent name on it
if (this.host.indexOf('.') !== -1) {
var _parts = this.host.split('.')
this.host = _parts[0]
this.parentDomain = opts.parentDomain || _parts[1]
}

this.port = opts.port
this.fqdn = this.name + '.' + this.type + TLD
this.subtypes = opts.subtypes || null
this.subtypes = opts.subtypes || []
this.fqdn = serviceName.stringify({
instance: this.name,
name: this.type,
protocol: this.protocol,
parentDomain: this.parentDomain
})
this.txt = opts.txt || null
this.published = false

Expand All @@ -34,9 +45,13 @@ Service.prototype._records = function () {
return [rr_ptr(this), rr_srv(this), rr_txt(this)]
}

function rr_ptr (service) {
function rr_ptr (service, subtype) {
return {
name: service.type + TLD,
name: serviceName.stringify({
name: service.type,
protocol: service.protocol,
subtypes: service.subtypes
}),
type: 'PTR',
ttl: 28800,
data: service.fqdn
Expand All @@ -50,7 +65,7 @@ function rr_srv (service) {
ttl: 120,
data: {
port: service.port,
target: service.host
target: service.host + '.' + service.parentDomain
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dependencies": {
"mdns-txt": "^2.0.0",
"multicast-dns": "^5.0.0",
"multicast-dns-service-types": "^1.1.0"
"multicast-dns-service-types": "git+ssh://git@github.com:wesleytodd/multicast-dns-service-types.git#v2.0.0"
},
"devDependencies": {
"after-all": "^2.0.2",
Expand Down
48 changes: 47 additions & 1 deletion test/bonjour.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ test('bonjour.find', function (bonjour, t) {
setTimeout(function () {
bonjour.destroy()
t.end()
}, 50)
}, 1000)
}
})
})
Expand Down Expand Up @@ -133,3 +133,49 @@ test('bonjour.findOne - emitter', function (bonjour, t) {
bonjour.publish({ name: 'Emitter', type: 'test', port: 3000 }).on('up', next())
bonjour.publish({ name: 'Invalid', type: 'test2', port: 3000 }).on('up', next())
})

test('bonjour.findOne - subtype', function (bonjour, t) {
var next = afterAll(function () {
var browser = bonjour.find({ type: 'bar', subtypes: ['sub1'] })
browser.on('up', function (s) {
t.equal(s.name, 'Foo')
t.equal(s.port, 3000)
// use timeout in an attempt to make sure the invalid record doesn't
// bubble up
setTimeout(function () {
bonjour.destroy()
t.end()
}, 2000)
})
})

bonjour.publish({ name: 'Foo', type: 'bar', port: 3000, subtypes: ['sub1'] }).on('up', next())
bonjour.publish({ name: 'Invalid', type: 'bar', port: 3001, subtypes: ['sub2'] }).on('up', next())
})

test('bonjour.find - all of subtype', function (bonjour, t) {
var next = afterAll(function () {
var browser = bonjour.find({ type: 'baz' })
var ups = 0

browser.on('up', function (s) {
if (s.name === 'Foo') {
t.equal(s.name, 'Foo')
t.equal(s.fqdn, 'Foo._baz._tcp.local')
t.equal(s.port, 3000)
} else if (s.name === 'Bar') {
t.equal(s.name, 'Bar')
t.equal(s.fqdn, 'Bar._baz._tcp.local')
t.equal(s.port, 3001)
}

if (++ups === 2) {
bonjour.destroy()
t.end()
}
})
})

bonjour.publish({ name: 'Foo', type: 'baz', port: 3000, subtypes: ['sub1'] }).on('up', next())
bonjour.publish({ name: 'Bar', type: 'baz', port: 3001, subtypes: ['sub2'] }).on('up', next())
})
29 changes: 14 additions & 15 deletions test/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ test('minimal', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', port: 3000 })
t.equal(s.name, 'Foo Bar')
t.equal(s.protocol, 'tcp')
t.equal(s.type, '_http._tcp')
t.equal(s.host, os.hostname())
t.equal(s.type, 'http')
t.equal(s.host, os.hostname().split('.')[0])
t.equal(s.port, 3000)
t.equal(s.fqdn, 'Foo Bar._http._tcp.local')
t.equal(s.txt, null)
t.equal(s.subtypes, null)
t.deepEqual(s.subtypes, [])
t.equal(s.published, false)
t.end()
})
Expand All @@ -47,7 +47,8 @@ test('protocol', function (t) {

test('host', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', port: 3000, host: 'example.com' })
t.deepEqual(s.host, 'example.com')
t.deepEqual(s.host, 'example')
t.deepEqual(s.parentDomain, 'com')
t.end()
})

Expand All @@ -59,20 +60,18 @@ test('txt', function (t) {

test('_records() - minimal', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', protocol: 'tcp', port: 3000 })
t.deepEqual(s._records(), [
{ data: s.fqdn, name: '_http._tcp.local', ttl: 28800, type: 'PTR' },
{ data: { port: 3000, target: os.hostname() }, name: s.fqdn, ttl: 120, type: 'SRV' },
{ data: new Buffer('00', 'hex'), name: s.fqdn, ttl: 4500, type: 'TXT' }
])
var r = s._records()
t.deepEqual(r[0], { data: s.fqdn, name: '_http._tcp.local', ttl: 28800, type: 'PTR' })
t.deepEqual(r[1], { data: { port: 3000, target: os.hostname() }, name: s.fqdn, ttl: 120, type: 'SRV' })
t.deepEqual(r[2], { data: new Buffer('00', 'hex'), name: s.fqdn, ttl: 4500, type: 'TXT' })
t.end()
})

test('_records() - everything', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', protocol: 'tcp', port: 3000, host: 'example.com', txt: { foo: 'bar' } })
t.deepEqual(s._records(), [
{ data: s.fqdn, name: '_http._tcp.local', ttl: 28800, type: 'PTR' },
{ data: { port: 3000, target: 'example.com' }, name: s.fqdn, ttl: 120, type: 'SRV' },
{ data: new Buffer('07666f6f3d626172', 'hex'), name: s.fqdn, ttl: 4500, type: 'TXT' }
])
var s = new Service({ name: 'Foo Bar', type: 'http', protocol: 'tcp', port: 3000, host: 'example.com', txt: { foo: 'bar' }, subtypes: ['foo', 'bar'] })
var r = s._records()
t.deepEqual(r[0], { data: s.fqdn, name: 'foo.bar._sub._http._tcp.local', ttl: 28800, type: 'PTR' })
t.deepEqual(r[1], { data: { port: 3000, target: 'example.com' }, name: s.fqdn, ttl: 120, type: 'SRV' })
t.deepEqual(r[2], { data: new Buffer('07666f6f3d626172', 'hex'), name: s.fqdn, ttl: 4500, type: 'TXT' })
t.end()
})