@homebridge/ciao
Version:
ciao is a RFC 6763 compliant dns-sd library, advertising on multicast dns (RFC 6762) implemented in plain Typescript/JavaScript
97 lines • 3.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueuedResponse = void 0;
/**
* Represents a delay response packet which is going to be sent over multicast.
*/
class QueuedResponse {
constructor(packet, interfaceName) {
this.timeOfCreation = Date.now(); // epoch time millis
this.estimatedTimeToBeSent = 0; // epoch time millis
this.delay = -1;
this.packet = packet;
this.interfaceName = interfaceName;
}
getPacket() {
return this.packet;
}
/**
* This method returns the total delay of the represented dns response packet.
* If this QueuedResponse consists of already combined packets
* (meaning other packets already got delayed in order to be sent out with this packet),
* the totalDelay will represent the maximum delay of any contained packet.
*
* @returns The total delay.
*/
getTimeSinceCreation() {
return Date.now() - this.timeOfCreation;
}
getTimeTillSent() {
return Math.max(0, this.estimatedTimeToBeSent - Date.now());
}
calculateRandomDelay() {
this.delay = Math.random() * 100 + 20; // delay of 20ms - 120ms
this.estimatedTimeToBeSent = Date.now() + this.delay;
}
scheduleResponse(callback) {
this.timer = setTimeout(callback, this.delay);
this.timer.unref(); // timer doesn't prevent termination
}
delayWouldBeInTimelyManner(next) {
const delay = next.estimatedTimeToBeSent - this.timeOfCreation;
return delay <= QueuedResponse.MAX_DELAY;
}
/**
* Combines this queue response packet with the {@code next} queued response packet if those can be combined.
* Packets can be combined if the udpPayloadSize allows for it AND if the current packet
* won't be delayed more than 500 ms from its time of creation AND the packets get sent on the same interface.
*
* @param next - A queued response which is schedule AFTER the current queued response.
* @returns {@code true} will be returned if the queued response was combined with the specified {@code next} response.
*/
combineWithNextPacketIfPossible(next) {
// below check, which is commented out would be necessary, current implementation will check that
// with function above, thus there is no need to check again.
/*
if (!this.delayWouldBeInTimelyManner(next)) {
return false;
}
*/
if (this.interfaceName !== next.interfaceName) {
// can't combine packets which get sent via different interfaces
return false;
}
if (!next.packet.canBeCombinedWith(this.packet)) {
// packets can't be combined
return false;
}
next.packet.combineWith(this.packet);
next.timeOfCreation = Math.min(this.timeOfCreation, next.timeOfCreation);
if (this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
this.delayed = true;
return true;
}
cancel() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
}
combineWithUniqueResponseIfPossible(response, interfaceName) {
if (this.interfaceName !== interfaceName) {
// can't combine packets which get sent via different interfaces
return false;
}
if (!this.packet.canBeCombinedWith(response.asPacket())) {
return false; // packets can't be combined
}
this.packet.combineWith(response.asPacket());
return true;
}
}
exports.QueuedResponse = QueuedResponse;
QueuedResponse.MAX_DELAY = 500; // milliseconds
//# sourceMappingURL=QueuedResponse.js.map