Skip to content

Commit 30abed0

Browse files
authored
Merge pull request #55 from Julusian/feat/ttl-and-expire
feat: track service ttl and lastSeen
2 parents eb0c305 + ad9559c commit 30abed0

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ Stop looking for matching services.
139139

140140
Broadcast the query again.
141141

142+
#### `browser.expire()`
143+
144+
Check any services for an expired TTL and emit stop events.
145+
142146
### Service
143147

144148
#### `Event: up`

src/lib/browser.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,21 @@ export class Browser extends EventEmitter {
9595
})
9696
}
9797

98+
const receiveTime = Date.now()
99+
98100
Object.keys(nameMap).forEach(function (name) {
99101
// unregister all services shutting down
100102
self.goodbyes(name, packet).forEach(self.removeService.bind(self))
101103

102104
// register all new services
103-
var matches = self.buildServicesFor(name, packet, self.txt, rinfo)
105+
var matches = self.buildServicesFor(name, packet, self.txt, rinfo, receiveTime)
104106
if (matches.length === 0) return
105107

106108
matches.forEach((service: Service) => {
107-
if (self.serviceMap[service.fqdn]) {
108-
self.updateService(service)
109+
const existingService = self._services.find((s) => dnsEqual(s.fqdn, service.fqdn))
110+
if (existingService) {
111+
existingService.lastSeen = service.lastSeen
112+
self.updateService(existingService, service)
109113
return
110114
}
111115
self.addService(service)
@@ -128,6 +132,20 @@ export class Browser extends EventEmitter {
128132
this.mdns.query(this.name, 'PTR')
129133
}
130134

135+
public expire() {
136+
const currentTime = Date.now()
137+
138+
this._services = this._services.filter((service) => {
139+
if(!service.ttl || service.lastSeen === undefined) return true // No expiry
140+
const expireTime = service.lastSeen + service.ttl * 1000
141+
if(expireTime < currentTime) {
142+
this.emit('down', service)
143+
return false
144+
}
145+
return true
146+
})
147+
}
148+
131149
public get services() {
132150
return this._services;
133151
}
@@ -140,9 +158,9 @@ export class Browser extends EventEmitter {
140158
this.emit('up', service)
141159
}
142160

143-
private updateService(service: Service) {
161+
private updateService(existingService:Service, service: Service) {
144162
// check if txt updated
145-
if (equalTxt(service.txt, this._services.find((s) => dnsEqual(s.fqdn, service.fqdn))?.txt || {})) return
163+
if (equalTxt(service.txt, existingService.txt || {})) return
146164
// if the new service is not allowed by the txt query, remove it
147165
if(!filterService(service, this.txtQuery)) {
148166
this.removeService(service.fqdn)
@@ -194,15 +212,17 @@ export class Browser extends EventEmitter {
194212
// https://tools.ietf.org/html/rfc6763#section-7.1
195213
// Selective Instance Enumeration (Subtypes)
196214
//
197-
private buildServicesFor(name: string, packet: any, txt: KeyValue, referer: any) {
215+
private buildServicesFor(name: string, packet: any, txt: KeyValue, referer: any, receiveTime: number) {
198216
var records = packet.answers.concat(packet.additionals).filter( (rr: ServiceRecord) => rr.ttl > 0) // ignore goodbye messages
199217

200218
return records
201219
.filter((rr: ServiceRecord) => rr.type === 'PTR' && dnsEqual(rr.name, name))
202220
.map((ptr: ServiceRecord) => {
203221
const service: KeyValue = {
204222
addresses: [],
205-
subtypes: []
223+
subtypes: [],
224+
ttl: ptr.ttl,
225+
lastSeen: receiveTime
206226
}
207227

208228
records.filter((rr: ServiceRecord) => {

src/lib/service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ export class Service extends EventEmitter {
5151
public addresses? : Array<string>
5252
public referer? : ServiceReferer
5353
public disableIPv6 : boolean
54+
public lastSeen? : number
55+
public ttl? : number
5456

5557
public probe : boolean = true
5658

0 commit comments

Comments
 (0)