@droneblocks/node-red-dexi
Version:
You want to make sure you don't lose any of your flow development. Make sure to map the host "flows" directory to the container directory as shown below. This will store the flow on your host machine if/when the container is destroyed.
100 lines (83 loc) • 2.81 kB
JavaScript
module.exports = function (RED){
var ROSLIB = require('roslib');
// Last known topic list, served if rosbridge is unreachable when the
// editor asks. Shape must match roslib's getTopics response.
let dexiTopics = { topics: [], types: [] }
let activeRos = null
function ROS2WebsocketServerNode(config) {
RED.nodes.createNode(this, config);
var node = this;
node.closing = false;
node.on("close", function() {
node.closing = true;
if (node.tout) { clearTimeout(node.tout); }
if (node.ros){
node.ros.close();
}
});
var trials = 0;
function startconn() { // Connect to remote endpoint
var ros = new ROSLIB.Ros({
url : config.url
});
node.ros = ros; // keep for closing
handleConnection(ros);
}
function handleConnection(ros) {
ros.on('connection', function() {
activeRos = ros;
node.emit('ros connected');
node.log('connected');
// Warm the fallback list. The editor queries live via /dexi/topics.
ros.getTopics((topicsResponse) => {
dexiTopics = topicsResponse
})
});
ros.on('error', function(error) {
trials++;
node.emit('ros error');
node.log('Error connecting : ', error);
//if(trials == 5) node.closing = true
});
ros.on('close', function() {
if (activeRos === ros) { activeRos = null; }
node.emit('ros closed');
node.log('Connection closed');
if (!node.closing) {
node.log('reconnecting');
node.tout = setTimeout(function(){ startconn(); }, 1000);
}
});
}
startconn();
node.closing = false;
}
// Expose "API" to the editor for displaying topics.
// Queried live on every request: a ROS node launched after node-red
// connected would otherwise never appear in the editor's topic list.
RED.httpAdmin.get('/dexi/topics', (req, res) => {
if (!activeRos) {
return res.json(dexiTopics)
}
let answered = false
const reply = (payload) => {
if (answered) { return }
answered = true
res.json(payload)
}
// Don't leave the editor spinning if rosapi never answers.
const timer = setTimeout(() => reply(dexiTopics), 3000)
activeRos.getTopics(
(topicsResponse) => {
clearTimeout(timer)
dexiTopics = topicsResponse
reply(topicsResponse)
},
() => {
clearTimeout(timer)
reply(dexiTopics)
}
)
})
RED.nodes.registerType("ros2-websocket-server", ROS2WebsocketServerNode);
};