signalk-server
Version:
An implementation of a [Signal K](http://signalk.org) server for boats.
84 lines (83 loc) • 2.94 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const dgram_1 = __importDefault(require("dgram"));
const util_1 = require("util");
const child_process_1 = require("child_process");
const os_1 = require("os");
const debug_1 = require("../debug");
const ports_1 = require("../ports");
const PUBLISH_PORT = 2053;
const MULTICAST_GROUP_IP = '239.2.1.1';
const debug = (0, debug_1.createDebug)('signalk-server:interfaces:mfd_webapps');
const execP = (0, util_1.promisify)(child_process_1.exec);
// For debugging you can use
// tcpdump -i en0 -A -v net 239.2.1.1
// eslint-disable-next-line @typescript-eslint/no-explicit-any
module.exports = (theApp) => {
return {
start() {
const port = (0, ports_1.getExternalPort)(theApp);
const protocol = theApp.config.settings.ssl ? 'https' : 'http';
const publishToNavico = getPublishToNavico(protocol, port);
setInterval(() => publishToNavico(), 10 * 1000);
}
};
};
const getPublishMessage = (protocol, address, port) => {
const prefix = `${protocol}://${address}:${port}`;
return JSON.stringify({
Version: '1',
Source: 'SignalK',
IP: address,
FeatureName: 'Signal K webapps',
Text: [
{
Language: 'en',
Name: 'Signal K',
Description: 'Signal K webapps'
}
],
Icon: `${prefix}/signalk-logo-transparent.png`,
URL: `${prefix}/`,
OnlyShowOnClientIP: 'true',
BrowserPanel: {
Enable: true,
ProgressBarEnable: true,
MenuText: [
{
Language: 'en',
Name: 'Home'
}
]
}
});
};
const send = (msg, fromAddress, toAddress, port) => {
const socket = dgram_1.default.createSocket('udp4');
socket.once('listening', () => {
socket.send(msg, port, toAddress, () => {
socket.close();
debug(`${fromAddress}=>${toAddress} @${port} ${msg}`);
});
});
socket.bind(PUBLISH_PORT, fromAddress);
};
const getPublishToNavico = (protocol, port) => async () => {
let addresses = [];
for (const [_name, infos] of Object.entries((0, os_1.networkInterfaces)())) {
for (const addressInfo of infos || []) {
if (addressInfo.family === 'IPv4') {
addresses.push(addressInfo.address);
}
}
}
if (process.env.MFD_ADDRESS_SCRIPT) {
addresses = (await execP(process.env.MFD_ADDRESS_SCRIPT)).stdout
.trim()
.split(',');
}
addresses.forEach((address) => send(getPublishMessage(protocol, address, port), address, MULTICAST_GROUP_IP, PUBLISH_PORT));
};