bonjour-hap 3.10.3-beta.0 → 3.10.3-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +12 -1
- package/index.js +20 -5
- package/lib/Browser.js +12 -2
- package/lib/Prober.js +1 -1
- package/lib/Registry.js +8 -3
- package/lib/Server.js +11 -5
- package/lib/Service.js +12 -6
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -149,7 +149,18 @@ export interface Bonjour {
|
|
|
149
149
|
options: BonjourFindOptions,
|
|
150
150
|
callback?: (service: BonjourService) => void
|
|
151
151
|
): Browser;
|
|
152
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Tear down the responder. Goodbye records are broadcast for every
|
|
154
|
+
* published service before the underlying mdns socket is closed.
|
|
155
|
+
* The optional callback fires once teardown is complete.
|
|
156
|
+
*/
|
|
157
|
+
destroy(callback?: () => void): void;
|
|
158
|
+
/**
|
|
159
|
+
* Emitted when the underlying mdns socket reports an error or an
|
|
160
|
+
* outgoing response fails. If no listener is attached, the error is
|
|
161
|
+
* logged to `console.warn` so it does not crash the process.
|
|
162
|
+
*/
|
|
163
|
+
on(event: "error", listener: (err: Error) => void): this;
|
|
153
164
|
}
|
|
154
165
|
|
|
155
166
|
export interface BonjourFactory {
|
package/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const util = require('util')
|
|
4
|
+
const EventEmitter = require('events').EventEmitter
|
|
3
5
|
const Registry = require('./lib/Registry.js')
|
|
4
6
|
const Server = require('./lib/Server.js')
|
|
5
7
|
const Browser = require('./lib/Browser.js')
|
|
@@ -7,11 +9,22 @@ const Browser = require('./lib/Browser.js')
|
|
|
7
9
|
function Bonjour (opts) {
|
|
8
10
|
if (!(this instanceof Bonjour)) { return new Bonjour(opts) }
|
|
9
11
|
|
|
12
|
+
EventEmitter.call(this)
|
|
13
|
+
|
|
10
14
|
this._server = new Server(opts)
|
|
11
15
|
this._registry = new Registry(this._server)
|
|
16
|
+
this._server.on('error', err => {
|
|
17
|
+
if (this.listenerCount('error') > 0) {
|
|
18
|
+
this.emit('error', err)
|
|
19
|
+
} else {
|
|
20
|
+
console.warn('bonjour-hap:', err.message || err)
|
|
21
|
+
}
|
|
22
|
+
})
|
|
12
23
|
}
|
|
13
24
|
|
|
14
|
-
Bonjour
|
|
25
|
+
util.inherits(Bonjour, EventEmitter)
|
|
26
|
+
|
|
27
|
+
Object.assign(Bonjour.prototype, {
|
|
15
28
|
publish: function (opts) {
|
|
16
29
|
return this._registry.publish(opts)
|
|
17
30
|
},
|
|
@@ -33,10 +46,12 @@ Bonjour.prototype = {
|
|
|
33
46
|
return browser
|
|
34
47
|
},
|
|
35
48
|
|
|
36
|
-
destroy: function () {
|
|
37
|
-
this._registry.destroy()
|
|
38
|
-
|
|
49
|
+
destroy: function (cb) {
|
|
50
|
+
this._registry.destroy(() => {
|
|
51
|
+
this._server.mdns.destroy()
|
|
52
|
+
if (cb) cb()
|
|
53
|
+
})
|
|
39
54
|
}
|
|
40
|
-
}
|
|
55
|
+
})
|
|
41
56
|
|
|
42
57
|
module.exports = Bonjour
|
package/lib/Browser.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const util = require('util')
|
|
4
4
|
const EventEmitter = require('events').EventEmitter
|
|
5
5
|
const serviceName = require('multicast-dns-service-types')
|
|
6
|
+
const deepEqual = require('fast-deep-equal')
|
|
6
7
|
const dnsEqual = require('./utils/dnsEqual')
|
|
7
8
|
const dnsTxt = require('./utils/txtDecoder')
|
|
8
9
|
|
|
@@ -35,7 +36,7 @@ function Browser (mdns, opts, onup) {
|
|
|
35
36
|
this._mdns = mdns
|
|
36
37
|
this._onresponse = null
|
|
37
38
|
this._serviceMap = {}
|
|
38
|
-
this._txt = dnsTxt(opts.txt)
|
|
39
|
+
this._txt = dnsTxt(opts && opts.txt)
|
|
39
40
|
|
|
40
41
|
if (!opts || !opts.type) {
|
|
41
42
|
this._name = WILDCARD
|
|
@@ -67,7 +68,7 @@ Browser.prototype.start = function () {
|
|
|
67
68
|
this._onresponse = function (packet, rinfo) {
|
|
68
69
|
if (self._wildcard) {
|
|
69
70
|
packet.answers.forEach(function (answer) {
|
|
70
|
-
if (answer.type !== 'PTR' || answer.name
|
|
71
|
+
if (answer.type !== 'PTR' || !dnsEqual(answer.name, self._name) || answer.data in nameMap) return
|
|
71
72
|
nameMap[answer.data] = true
|
|
72
73
|
self._mdns.query(answer.data, 'PTR')
|
|
73
74
|
})
|
|
@@ -123,10 +124,19 @@ Browser.prototype._updateService = function (service) {
|
|
|
123
124
|
return false
|
|
124
125
|
})
|
|
125
126
|
if (!cachedService) return
|
|
127
|
+
if (!serviceChanged(cachedService, service)) return
|
|
126
128
|
this.services[index] = service
|
|
127
129
|
this.emit('update', service)
|
|
128
130
|
}
|
|
129
131
|
|
|
132
|
+
function serviceChanged (a, b) {
|
|
133
|
+
return a.host !== b.host ||
|
|
134
|
+
a.port !== b.port ||
|
|
135
|
+
!deepEqual(a.addresses, b.addresses) ||
|
|
136
|
+
!deepEqual(a.subtypes, b.subtypes) ||
|
|
137
|
+
!deepEqual(a.txt, b.txt)
|
|
138
|
+
}
|
|
139
|
+
|
|
130
140
|
Browser.prototype._removeService = function (fqdn) {
|
|
131
141
|
let service, index
|
|
132
142
|
this.services.some(function (s, i) {
|
package/lib/Prober.js
CHANGED
package/lib/Registry.js
CHANGED
|
@@ -26,8 +26,13 @@ Registry.prototype = {
|
|
|
26
26
|
this._services = []
|
|
27
27
|
},
|
|
28
28
|
|
|
29
|
-
destroy: function () {
|
|
30
|
-
|
|
29
|
+
destroy: function (cb) {
|
|
30
|
+
const services = this._services.slice()
|
|
31
|
+
this._services = []
|
|
32
|
+
this._tearDown(services, () => {
|
|
33
|
+
for (let i = 0; i < services.length; i++) { services[i].destroy() }
|
|
34
|
+
if (cb) cb()
|
|
35
|
+
})
|
|
31
36
|
},
|
|
32
37
|
|
|
33
38
|
/**
|
|
@@ -46,7 +51,7 @@ Registry.prototype = {
|
|
|
46
51
|
|
|
47
52
|
const records = services.map(function (service) {
|
|
48
53
|
service.deactivate()
|
|
49
|
-
const records = service._records(
|
|
54
|
+
const records = service._records()
|
|
50
55
|
records.forEach(function (record) {
|
|
51
56
|
record.ttl = 0 // prepare goodbye message
|
|
52
57
|
})
|
package/lib/Server.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const util = require('util')
|
|
4
|
+
const EventEmitter = require('events').EventEmitter
|
|
3
5
|
const multicastdns = require('multicast-dns')
|
|
4
6
|
const dnsEqual = require('./utils/dnsEqual')
|
|
5
7
|
const helpers = require('./helpers.js')
|
|
6
8
|
|
|
7
9
|
const Server = function (opts) {
|
|
10
|
+
EventEmitter.call(this)
|
|
8
11
|
this.mdns = multicastdns(opts)
|
|
9
12
|
this.mdns.setMaxListeners(0)
|
|
10
13
|
this.registry = {}
|
|
11
14
|
this.mdns.on('query', this._respondToQuery.bind(this))
|
|
15
|
+
this.mdns.on('error', err => this.emit('error', err))
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
Server
|
|
18
|
+
util.inherits(Server, EventEmitter)
|
|
19
|
+
|
|
20
|
+
Object.assign(Server.prototype, {
|
|
15
21
|
_respondToQuery: function (query) {
|
|
16
22
|
for (let i = 0; i < query.questions.length; i++) {
|
|
17
23
|
const question = query.questions[i]
|
|
@@ -24,7 +30,7 @@ Server.prototype = {
|
|
|
24
30
|
? Object.keys(this.registry).map(this._recordsFor.bind(this, name)).flat()
|
|
25
31
|
: this._recordsFor(name, type)
|
|
26
32
|
|
|
27
|
-
if (answers.length === 0)
|
|
33
|
+
if (answers.length === 0) continue
|
|
28
34
|
|
|
29
35
|
// generate the additionals section
|
|
30
36
|
let additionals = []
|
|
@@ -57,7 +63,7 @@ Server.prototype = {
|
|
|
57
63
|
answers,
|
|
58
64
|
additionals
|
|
59
65
|
}, err => {
|
|
60
|
-
if (err)
|
|
66
|
+
if (err) this.emit('error', err)
|
|
61
67
|
})
|
|
62
68
|
}
|
|
63
69
|
},
|
|
@@ -89,7 +95,7 @@ Server.prototype = {
|
|
|
89
95
|
if (!(type in this.registry)) { continue }
|
|
90
96
|
|
|
91
97
|
this.registry[type] = this.registry[type].filter(r => {
|
|
92
|
-
return r.name
|
|
98
|
+
return !dnsEqual(r.name, record.name)
|
|
93
99
|
})
|
|
94
100
|
}
|
|
95
101
|
},
|
|
@@ -103,6 +109,6 @@ Server.prototype = {
|
|
|
103
109
|
})
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
}
|
|
112
|
+
})
|
|
107
113
|
|
|
108
114
|
module.exports = Server
|
package/lib/Service.js
CHANGED
|
@@ -83,7 +83,7 @@ const proto = {
|
|
|
83
83
|
|
|
84
84
|
stop: function (cb) {
|
|
85
85
|
if (!this._activated) {
|
|
86
|
-
cb()
|
|
86
|
+
if (cb) cb()
|
|
87
87
|
return
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -109,19 +109,25 @@ const proto = {
|
|
|
109
109
|
if (this.timer) { clearTimeout(this.timer) }
|
|
110
110
|
|
|
111
111
|
this.delay = 1000
|
|
112
|
+
this._emitAnnounce(silent)
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
_emitAnnounce: function (silent) {
|
|
116
|
+
if (this._destroyed) { return }
|
|
112
117
|
this.emit('service-announce-request', this.packet, silent || false, this.onAnnounceComplete.bind(this))
|
|
113
118
|
},
|
|
114
119
|
|
|
115
120
|
onAnnounceComplete: function () {
|
|
121
|
+
if (this._destroyed || !this._activated) return
|
|
122
|
+
|
|
116
123
|
if (!this.published) {
|
|
117
|
-
this._activated = true // not sure if this is needed here
|
|
118
124
|
this.published = true
|
|
119
125
|
this.emit('up')
|
|
120
126
|
}
|
|
121
127
|
|
|
122
128
|
this.delay = this.delay * REANNOUNCE_FACTOR
|
|
123
|
-
if (this.delay < REANNOUNCE_MAX_MS
|
|
124
|
-
this.timer = setTimeout(this.
|
|
129
|
+
if (this.delay < REANNOUNCE_MAX_MS) {
|
|
130
|
+
this.timer = setTimeout(this._emitAnnounce.bind(this), this.delay).unref()
|
|
125
131
|
} else {
|
|
126
132
|
this.timer = undefined
|
|
127
133
|
this.delay = undefined
|
|
@@ -145,12 +151,12 @@ const proto = {
|
|
|
145
151
|
this.published = false
|
|
146
152
|
},
|
|
147
153
|
|
|
148
|
-
_records: function (
|
|
154
|
+
_records: function () {
|
|
149
155
|
const records = [this._rrPtr(), this._rrSrv(), this._rrTxt()]
|
|
150
156
|
|
|
151
157
|
records.push(...this._addressRecords())
|
|
152
158
|
|
|
153
|
-
if (
|
|
159
|
+
if (this.addUnsafeServiceEnumerationRecord) {
|
|
154
160
|
records.push(this._rrMetaPtr())
|
|
155
161
|
}
|
|
156
162
|
|