@@ -77,6 +77,10 @@ class MDNS {
77
77
78
78
protected queries : Map < string , PromiseCancellable < void > > = new Map ( ) ;
79
79
protected advertisements : Map < string , PromiseCancellable < void > > = new Map ( ) ;
80
+ /**
81
+ * Represents the advertisements and queries that have been cancelled and are in the process of stopping
82
+ */
83
+ protected stoppingTasks : Set < PromiseCancellable < unknown > > = new Set ( ) ;
80
84
81
85
public constructor ( {
82
86
getNetworkInterfaces = utils . getNetworkInterfaces ,
@@ -465,11 +469,13 @@ class MDNS {
465
469
advertisementKey : string ,
466
470
socket ?: MulticastSocketInfo | Array < MulticastSocketInfo > ,
467
471
) {
472
+ // If the advertisement already, exists cancel and restart it
468
473
const advertisement = this . advertisements . get ( advertisementKey ) ;
469
474
if ( advertisement != null ) {
470
475
advertisement . cancel ( ) ;
476
+ this . stoppingTasks . add ( advertisement ) ;
471
477
}
472
-
478
+ // Construct the PromiseCancellable
473
479
const abortController = new AbortController ( ) ;
474
480
const promise = new PromiseCancellable < void > ( async ( resolve , reject ) => {
475
481
await this . sendMulticastPacket ( packet , socket ) . catch ( reject ) ;
@@ -495,18 +501,18 @@ class MDNS {
495
501
{ once : true } ,
496
502
) ;
497
503
} , abortController ) ;
498
-
499
- // Delete the advertisement key whether reject or resolve
504
+ // Delete the advertisement key and delete it from stoppingTasks whether reject or resolve
500
505
promise . then (
501
506
( ) => {
507
+ this . stoppingTasks . delete ( promise ) ;
502
508
this . advertisements . delete ( advertisementKey ) ;
503
509
} ,
504
510
( reason ) => {
505
- this . dispatchEvent ( new events . EventMDNSError ( { detail : reason } ) ) ;
511
+ this . stoppingTasks . delete ( promise ) ;
506
512
this . advertisements . delete ( advertisementKey ) ;
513
+ this . dispatchEvent ( new events . EventMDNSError ( { detail : reason } ) ) ;
507
514
} ,
508
515
) ;
509
-
510
516
this . advertisements . set ( advertisementKey , promise ) ;
511
517
}
512
518
@@ -1082,13 +1088,19 @@ class MDNS {
1082
1088
this . logger . info ( `Stop ${ this . constructor . name } ` ) ;
1083
1089
1084
1090
// Cancel Queries and Advertisements
1091
+ const stoppingTasks = [ ...this . stoppingTasks ] ;
1085
1092
for ( const query of this . queries . values ( ) ) {
1086
1093
query . cancel ( ) ;
1094
+ stoppingTasks . push ( query ) ;
1087
1095
}
1088
1096
for ( const advertisement of this . advertisements . values ( ) ) {
1089
1097
advertisement . cancel ( ) ;
1098
+ stoppingTasks . push ( advertisement ) ;
1090
1099
}
1100
+ // We don't care if any Queries or Advertisements have failed, just that they have stopped.
1101
+ await Promise . allSettled ( stoppingTasks ) ;
1091
1102
1103
+ const goodbyeProms : Array < Promise < unknown > > = [ ] ;
1092
1104
// Send the goodbye packet
1093
1105
const serviceResourceRecords = utils . toServiceResourceRecords (
1094
1106
[ ...this . _localServices . values ( ) ] ,
@@ -1124,8 +1136,10 @@ class MDNS {
1124
1136
additionals : [ ] ,
1125
1137
authorities : [ ] ,
1126
1138
} ;
1127
- await this . sendMulticastPacket ( advertisePacket , socketInfo ) ;
1139
+ goodbyeProms . push ( this . sendMulticastPacket ( advertisePacket , socketInfo ) ) ;
1128
1140
}
1141
+ // We don't care if any goodbye packets failed to send, just that they have completed
1142
+ await Promise . allSettled ( goodbyeProms ) ;
1129
1143
1130
1144
// Clear Services and Cache
1131
1145
await this . localRecordCache . destroy ( ) ;
@@ -1190,10 +1204,10 @@ class MDNS {
1190
1204
hosts : [ ] ,
1191
1205
} ;
1192
1206
const fqdn = utils . toFqdn ( service ) ;
1193
-
1207
+ // Update the service even if it is there
1194
1208
this . _localServices . set ( fqdn , service ) ;
1195
1209
this . localRecordCacheDirty = true ;
1196
-
1210
+ // Don't bother to advertise if the param is not enabled
1197
1211
if ( ! advertise ) return ;
1198
1212
const advertisePacket : Packet = {
1199
1213
id : this . _id ,
@@ -1232,10 +1246,10 @@ class MDNS {
1232
1246
type,
1233
1247
protocol,
1234
1248
} ) ;
1235
-
1249
+ // If there is no found service, don't bother
1236
1250
const foundService = this . _localServices . get ( fqdn ) ;
1237
1251
if ( foundService == null ) return ;
1238
-
1252
+ // Delete and advertise the service
1239
1253
this . _localServices . delete ( fqdn ) ;
1240
1254
this . localRecordCacheDirty = true ;
1241
1255
const advertisePacket : Packet = {
@@ -1287,6 +1301,7 @@ class MDNS {
1287
1301
const existingQuery = this . queries . get ( serviceDomain ) ;
1288
1302
if ( existingQuery != null ) {
1289
1303
existingQuery . cancel ( ) ;
1304
+ this . stoppingTasks . add ( existingQuery ) ;
1290
1305
this . queries . delete ( serviceDomain ) ;
1291
1306
}
1292
1307
const questionRecord : QuestionRecord = {
@@ -1307,7 +1322,7 @@ class MDNS {
1307
1322
additionals : [ ] ,
1308
1323
authorities : [ ] ,
1309
1324
} ;
1310
-
1325
+ // Create the PromiseCancellable
1311
1326
const abortController = new AbortController ( ) ;
1312
1327
const promise = new PromiseCancellable < void > ( async ( resolve , reject ) => {
1313
1328
await this . sendMulticastPacket ( queryPacket ) . catch ( reject ) ;
@@ -1341,17 +1356,19 @@ class MDNS {
1341
1356
{ once : true } ,
1342
1357
) ;
1343
1358
} , abortController ) ;
1344
-
1359
+ // After promise resolves/rejects
1345
1360
promise . then (
1346
1361
( ) => {
1362
+ this . stoppingTasks . delete ( promise ) ;
1347
1363
this . queries . delete ( serviceDomain ) ;
1348
1364
} ,
1349
1365
( reason ) => {
1366
+ this . stoppingTasks . delete ( promise ) ;
1350
1367
this . queries . delete ( serviceDomain ) ;
1351
1368
this . dispatchEvent ( new events . EventMDNSError ( { detail : reason } ) ) ;
1352
1369
} ,
1353
1370
) ;
1354
-
1371
+ // Set in queries map
1355
1372
this . queries . set ( serviceDomain , promise ) ;
1356
1373
}
1357
1374
@@ -1376,6 +1393,7 @@ class MDNS {
1376
1393
const existingQuery = this . queries . get ( serviceDomain ) ;
1377
1394
if ( existingQuery != null ) {
1378
1395
existingQuery . cancel ( ) ;
1396
+ this . stoppingTasks . add ( existingQuery ) ;
1379
1397
this . queries . delete ( serviceDomain ) ;
1380
1398
}
1381
1399
}
0 commit comments