sacn
Version:
💡 🎠Send and Receive sACN data (DMX over IP)
91 lines (90 loc) • 4.66 kB
JavaScript
"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _Sender_destinationIp, _Sender_loopId, _Sender_latestPacketOptions;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Sender = void 0;
const dgram_1 = require("dgram");
const events_1 = require("events");
const util_1 = require("./util");
const packet_1 = require("./packet");
class Sender extends events_1.EventEmitter {
constructor({ universe, port = 5568, reuseAddr = false, minRefreshRate = 0, defaultPacketOptions, iface, useUnicastDestination, }) {
super();
/**
* this is normally a multicast address, but it could be
* a unicast address if the user configures `useUnicastDestination`
*/
_Sender_destinationIp.set(this, void 0);
this.sequence = 0;
this.resendStatus = false;
_Sender_loopId.set(this, void 0);
/**
* we keep track of the most recent value of every channel, so that we can
* send it regulally if `refreshRate` != 0. `undefined` if nothing has been
* sent yet.
*/
_Sender_latestPacketOptions.set(this, void 0);
this.port = port;
this.universe = universe;
__classPrivateFieldSet(this, _Sender_destinationIp, useUnicastDestination || (0, util_1.multicastGroup)(universe), "f");
this.defaultPacketOptions = defaultPacketOptions;
this.socket = (0, dgram_1.createSocket)({ type: 'udp4', reuseAddr });
if (iface || reuseAddr) {
// prevent different behavior due to socket.bind() side effects, but binding the socket when reuseAddr: false could cause problems
this.socket.bind(port, () => {
// need to bind socket first
if (iface) {
this.socket.setMulticastInterface(iface);
}
});
}
if (minRefreshRate) {
__classPrivateFieldSet(this, _Sender_loopId, setInterval(() => this.reSend(), 1000 / minRefreshRate), "f");
}
}
send(packet) {
const finalPacket = Object.assign(Object.assign({}, this.defaultPacketOptions), packet);
__classPrivateFieldSet(this, _Sender_latestPacketOptions, finalPacket, "f");
return new Promise((resolve, reject) => {
const { buffer } = new packet_1.Packet(Object.assign(Object.assign({}, finalPacket), { universe: this.universe, sequence: this.sequence }));
this.sequence = (this.sequence + 1) % 256;
this.socket.send(buffer, this.port, __classPrivateFieldGet(this, _Sender_destinationIp, "f"), (err) => err ? reject(err) : resolve());
});
}
reSend() {
if (__classPrivateFieldGet(this, _Sender_latestPacketOptions, "f")) {
this.send(__classPrivateFieldGet(this, _Sender_latestPacketOptions, "f"))
.then(() => {
this.updateResendStatus(true);
})
.catch((err) => {
this.updateResendStatus(false);
this.emit('error', err);
});
}
}
updateResendStatus(success) {
if (success !== this.resendStatus) {
this.resendStatus = success;
this.emit('changedResendStatus', success);
}
}
close() {
if (__classPrivateFieldGet(this, _Sender_loopId, "f"))
clearTimeout(__classPrivateFieldGet(this, _Sender_loopId, "f"));
this.socket.close();
return this;
}
}
exports.Sender = Sender;
_Sender_destinationIp = new WeakMap(), _Sender_loopId = new WeakMap(), _Sender_latestPacketOptions = new WeakMap();