@signalk/streams
Version:
Utilities for handling streams of Signal K data
145 lines (143 loc) • 5.89 kB
JavaScript
"use strict";
/*
* Copyright 2016 Teppo Kurki <teppo.kurki@iki.fi>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = require("stream");
const client_1 = require("@signalk/client");
class MdnsWs extends stream_1.Transform {
options;
selfHost;
selfPort;
remoteServers = {};
debug;
dataDebug;
handleContext;
signalkClient;
constructor(options) {
super({ objectMode: true });
this.options = options;
this.selfHost = options.app.config.getExternalHostname() + '.';
this.selfPort = options.app.config.getExternalPort();
this.remoteServers[this.selfHost + ':' + this.selfPort] = {};
const deltaStreamBehaviour = options.subscription ? 'none' : 'all';
const createDebug = options.createDebug ?? require('debug');
this.debug = createDebug('signalk:streams:mdns-ws');
this.dataDebug = createDebug('signalk:streams:mdns-ws-data');
this.debug(`deltaStreamBehaviour:${deltaStreamBehaviour}`);
this.handleContext = () => { };
if (options.selfHandling === 'manualSelf') {
if (options.remoteSelf) {
this.debug(`Using manual remote self ${options.remoteSelf}`);
this.handleContext = (delta) => {
if (delta.context === options.remoteSelf) {
delete delta.context;
}
};
}
else {
console.error('Manual self handling speficied but no remoteSelf configured');
}
}
if (options.ignoreServers) {
options.ignoreServers.forEach((s) => {
this.remoteServers[s] = {};
});
}
if (options.host && options.port) {
this.signalkClient = new client_1.Client({
hostname: options.host,
port: options.port,
useTLS: options.type === 'wss',
reconnect: true,
notifications: false,
autoConnect: false,
deltaStreamBehaviour,
rejectUnauthorized: !(options.selfsignedcert === true),
wsKeepaliveInterval: 10
});
this.connectClient(this.signalkClient);
}
else {
this.options.app.setProviderError(this.options.providerId, 'This connection is deprecated and must be deleted');
}
}
connectClient(client) {
client
.connect()
.then(() => {
this.options.app.setProviderStatus(this.options.providerId, `ws connection connected to ${client.options.hostname}:${client.options.port}`);
console.log(`ws connection connected to ${client.options.hostname}:${client.options.port}`);
if (this.options.selfHandling === 'useRemoteSelf') {
client
.API()
.then((api) => api.get('/self'))
.then((selfFromServer) => {
this.debug(`Mapping context ${selfFromServer} to self (empty context)`);
this.handleContext = (delta) => {
if (delta.context === selfFromServer) {
delete delta.context;
}
};
})
.catch((err) => {
console.error('Error retrieving self from remote server');
console.error(err);
});
}
this.remoteServers[client.options.hostname + ':' + client.options.port] = client;
if (this.options.subscription) {
let parsed;
try {
parsed = JSON.parse(this.options.subscription);
}
catch (ex) {
const error = ex;
this.options.app.setProviderError(this.options.providerId, `unable to parse subscription json: ${this.options.subscription}: ${error.message}`);
console.error(`unable to parse subscription json: ${this.options.subscription}: ${error.message}`);
return;
}
if (!Array.isArray(parsed)) {
parsed = [parsed];
}
;
parsed.forEach((sub, idx) => {
this.debug('sending subscription %j', sub);
client.subscribe(sub, String(idx));
});
}
})
.catch((err) => {
this.options.app.setProviderError(this.options.providerId, err.message);
console.error(err.message);
});
client.on('delta', (data) => {
if (data && data.updates) {
this.handleContext(data);
if (this.dataDebug.enabled) {
this.dataDebug(JSON.stringify(data));
}
data.updates.forEach((update) => {
update['$source'] =
`${this.options.providerId}.${client.options.hostname}:${client.options.port}`;
});
}
this.push(data);
});
}
_transform(chunk, encoding, done) {
done();
}
}
exports.default = MdnsWs;