mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add comms module
This commit is contained in:
parent
e6794a0c75
commit
16f8673ec0
@ -91,7 +91,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
var a = function() {
|
||||
(function() {
|
||||
var content = document.createElement("div");
|
||||
content.id = "tab-debug";
|
||||
|
||||
@ -114,84 +114,56 @@
|
||||
|
||||
var sbc = document.getElementById("debug-content");
|
||||
|
||||
var errornotification = null;
|
||||
|
||||
var messageCount = 0;
|
||||
|
||||
|
||||
function debugConnect() {
|
||||
//console.log("debug ws connecting");
|
||||
var path = location.hostname+":"+location.port+document.location.pathname;
|
||||
path = path+(path.slice(-1) == "/"?"":"/")+"debug/ws";
|
||||
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
|
||||
var ws = new WebSocket(path);
|
||||
ws.onopen = function() {
|
||||
if (errornotification) {
|
||||
errornotification.close();
|
||||
errornotification = null;
|
||||
}
|
||||
//console.log("debug ws connected");
|
||||
}
|
||||
ws.onmessage = function(event) {
|
||||
var o = JSON.parse(event.data);
|
||||
if (o.heartbeat) {
|
||||
return;
|
||||
}
|
||||
//console.log(msg);
|
||||
var msg = document.createElement("div");
|
||||
msg.onmouseover = function() {
|
||||
msg.style.borderRightColor = "#999";
|
||||
var n = RED.nodes.node(o.id);
|
||||
if (n) {
|
||||
n.highlighted = true;
|
||||
n.dirty = true;
|
||||
}
|
||||
RED.view.redraw();
|
||||
};
|
||||
msg.onmouseout = function() {
|
||||
msg.style.borderRightColor = "";
|
||||
var n = RED.nodes.node(o.id);
|
||||
if (n) {
|
||||
n.highlighted = false;
|
||||
n.dirty = true;
|
||||
}
|
||||
RED.view.redraw();
|
||||
};
|
||||
msg.onclick = function() {
|
||||
var node = RED.nodes.node(o.id);
|
||||
if (node) {
|
||||
RED.view.showWorkspace(node.z);
|
||||
}
|
||||
|
||||
};
|
||||
var name = (o.name?o.name:o.id).toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
var topic = (o.topic||"").toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
var payload = (o.msg||"").toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'')
|
||||
msg.innerHTML = '<span class="debug-message-date">'+getTimestamp()+'</span>'+
|
||||
'<span class="debug-message-name">['+name+']</span>'+
|
||||
(o.topic?'<span class="debug-message-topic">'+topic+'</span>':'')+
|
||||
'<span class="debug-message-payload">'+payload+'</span>';
|
||||
var atBottom = (sbc.scrollHeight-messages.offsetHeight-sbc.scrollTop) < 5;
|
||||
messageCount++;
|
||||
$(messages).append(msg);
|
||||
|
||||
if (messageCount > 200) {
|
||||
$("#debug-content .debug-message:first").remove();
|
||||
messageCount--;
|
||||
}
|
||||
if (atBottom) {
|
||||
$(sbc).scrollTop(sbc.scrollHeight);
|
||||
var handleDebugMessage = function(t,o) {
|
||||
var msg = document.createElement("div");
|
||||
msg.onmouseover = function() {
|
||||
msg.style.borderRightColor = "#999";
|
||||
var n = RED.nodes.node(o.id);
|
||||
if (n) {
|
||||
n.highlighted = true;
|
||||
n.dirty = true;
|
||||
}
|
||||
RED.view.redraw();
|
||||
};
|
||||
ws.onclose = function() {
|
||||
if (errornotification == null) {
|
||||
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true);
|
||||
msg.onmouseout = function() {
|
||||
msg.style.borderRightColor = "";
|
||||
var n = RED.nodes.node(o.id);
|
||||
if (n) {
|
||||
n.highlighted = false;
|
||||
n.dirty = true;
|
||||
}
|
||||
setTimeout(debugConnect,1000);
|
||||
RED.view.redraw();
|
||||
};
|
||||
msg.onclick = function() {
|
||||
var node = RED.nodes.node(o.id);
|
||||
if (node) {
|
||||
RED.view.showWorkspace(node.z);
|
||||
}
|
||||
|
||||
};
|
||||
var name = (o.name?o.name:o.id).toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
var topic = (o.topic||"").toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
var payload = (o.msg||"").toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
|
||||
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'')
|
||||
msg.innerHTML = '<span class="debug-message-date">'+getTimestamp()+'</span>'+
|
||||
'<span class="debug-message-name">['+name+']</span>'+
|
||||
(o.topic?'<span class="debug-message-topic">'+topic+'</span>':'')+
|
||||
'<span class="debug-message-payload">'+payload+'</span>';
|
||||
var atBottom = (sbc.scrollHeight-messages.offsetHeight-sbc.scrollTop) < 5;
|
||||
messageCount++;
|
||||
$(messages).append(msg);
|
||||
|
||||
if (messageCount > 200) {
|
||||
$("#debug-content .debug-message:first").remove();
|
||||
messageCount--;
|
||||
}
|
||||
}
|
||||
debugConnect();
|
||||
if (atBottom) {
|
||||
$(sbc).scrollTop(sbc.scrollHeight);
|
||||
}
|
||||
};
|
||||
RED.comms.subscribe("debug",handleDebugMessage);
|
||||
|
||||
$("#debug-tab-clear").click(function() {
|
||||
$(".debug-message").remove();
|
||||
@ -203,7 +175,7 @@
|
||||
RED.view.redraw();
|
||||
});
|
||||
|
||||
}();
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -51,35 +51,15 @@ module.exports = function(RED) {
|
||||
if (typeof msg.payload == "undefined") { msg.payload = "(undefined)"; }
|
||||
if (msg.payload instanceof Buffer) { msg.payload = "(Buffer) "+msg.payload.toString('hex'); }
|
||||
if (this.active) {
|
||||
DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path});
|
||||
sendDebug({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var lastSentTime = (new Date()).getTime();
|
||||
|
||||
setInterval(function() {
|
||||
var now = (new Date()).getTime();
|
||||
if (now-lastSentTime > 15000) {
|
||||
lastSentTime = now;
|
||||
for (var i in DebugNode.activeConnections) {
|
||||
var ws = DebugNode.activeConnections[i];
|
||||
try {
|
||||
var p = JSON.stringify({heartbeat:lastSentTime});
|
||||
ws.send(p);
|
||||
} catch(err) {
|
||||
util.log("[debug] ws heartbeat error : "+err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 15000);
|
||||
|
||||
|
||||
|
||||
|
||||
RED.nodes.registerType("debug",DebugNode);
|
||||
|
||||
DebugNode.send = function(msg) {
|
||||
function sendDebug(msg) {
|
||||
if (msg.msg instanceof Error) {
|
||||
msg.msg = msg.msg.toString();
|
||||
} else if (typeof msg.msg === 'object') {
|
||||
@ -106,47 +86,13 @@ module.exports = function(RED) {
|
||||
msg.msg = msg.msg.substr(0,debuglength) +" ....";
|
||||
}
|
||||
|
||||
for (var i in DebugNode.activeConnections) {
|
||||
var ws = DebugNode.activeConnections[i];
|
||||
try {
|
||||
var p = JSON.stringify(msg);
|
||||
ws.send(p);
|
||||
} catch(err) {
|
||||
util.log("[debug] ws error : "+err);
|
||||
}
|
||||
}
|
||||
lastSentTime = (new Date()).getTime();
|
||||
RED.comms.publish("debug",msg);
|
||||
}
|
||||
|
||||
DebugNode.activeConnections = [];
|
||||
|
||||
var path = RED.settings.httpAdminRoot || "/";
|
||||
path = path + (path.slice(-1) == "/" ? "":"/") + "debug/ws";
|
||||
|
||||
DebugNode.wsServer = new ws.Server({server:RED.server,path:path});
|
||||
DebugNode.wsServer.on('connection',function(ws) {
|
||||
DebugNode.activeConnections.push(ws);
|
||||
ws.on('close',function() {
|
||||
for (var i in DebugNode.activeConnections) {
|
||||
if (DebugNode.activeConnections[i] === ws) {
|
||||
DebugNode.activeConnections.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
ws.on('error', function(err) {
|
||||
util.log("[debug] ws error : "+err);
|
||||
});
|
||||
});
|
||||
|
||||
DebugNode.wsServer.on('error', function(err) {
|
||||
util.log("[debug] ws server error : "+err);
|
||||
});
|
||||
|
||||
DebugNode.logHandler = new events.EventEmitter();
|
||||
DebugNode.logHandler.on("log",function(msg) {
|
||||
if (msg.level == "warn" || msg.level == "error") {
|
||||
DebugNode.send(msg);
|
||||
sendDebug(msg);
|
||||
}
|
||||
});
|
||||
RED.log.addHandler(DebugNode.logHandler);
|
||||
|
@ -317,5 +317,6 @@
|
||||
<script src="red/ui/editor.js"></script>
|
||||
<script src="red/ui/library.js"></script>
|
||||
<script src="red/ui/notifications.js"></script>
|
||||
<script src="red/comms.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
61
public/red/comms.js
Normal file
61
public/red/comms.js
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright 2014 IBM Corp.
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
|
||||
RED.comms = function() {
|
||||
|
||||
var errornotification = null;
|
||||
var subscriptions = {};
|
||||
|
||||
function connectWS() {
|
||||
var path = location.hostname+":"+location.port+document.location.pathname;
|
||||
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
|
||||
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
|
||||
var ws = new WebSocket(path);
|
||||
ws.onopen = function() {
|
||||
if (errornotification) {
|
||||
errornotification.close();
|
||||
errornotification = null;
|
||||
}
|
||||
}
|
||||
ws.onmessage = function(event) {
|
||||
var msg = JSON.parse(event.data);
|
||||
var subscribers = subscriptions[msg.topic];
|
||||
if (subscribers) {
|
||||
for (var i=0;i<subscribers.length;i++) {
|
||||
subscribers[i](msg.topic,msg.data);
|
||||
}
|
||||
}
|
||||
};
|
||||
ws.onclose = function() {
|
||||
if (errornotification == null) {
|
||||
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true);
|
||||
}
|
||||
setTimeout(connectWS,1000);
|
||||
}
|
||||
}
|
||||
connectWS();
|
||||
|
||||
function subscribe(topic,callback) {
|
||||
if (subscriptions[topic] == null) {
|
||||
subscriptions[topic] = [];
|
||||
}
|
||||
subscriptions[topic].push(callback);
|
||||
}
|
||||
|
||||
return {
|
||||
subscribe: subscribe
|
||||
}
|
||||
}();
|
86
red/comms.js
Normal file
86
red/comms.js
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright 2014 IBM Corp.
|
||||
*
|
||||
* 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.
|
||||
**/
|
||||
|
||||
var ws = require("ws");
|
||||
var util = require("util");
|
||||
|
||||
var server;
|
||||
var settings;
|
||||
|
||||
var wsServer;
|
||||
var activeConnections = [];
|
||||
|
||||
var heartbeatTimer;
|
||||
var lastSentTime;
|
||||
|
||||
|
||||
function init(_server,_settings) {
|
||||
server = _server;
|
||||
settings = _settings;
|
||||
}
|
||||
|
||||
function start() {
|
||||
var path = settings.httpAdminRoot || "/";
|
||||
path = path + (path.slice(-1) == "/" ? "":"/") + "comms";
|
||||
wsServer = new ws.Server({server:server,path:path});
|
||||
|
||||
wsServer.on('connection',function(ws) {
|
||||
activeConnections.push(ws);
|
||||
ws.on('close',function() {
|
||||
for (var i=0;i<activeConnections.length;i++) {
|
||||
if (activeConnections[i] === ws) {
|
||||
activeConnections.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
ws.on('error', function(err) {
|
||||
util.log("[red:comms] error : "+err.toString());
|
||||
});
|
||||
});
|
||||
|
||||
wsServer.on('error', function(err) {
|
||||
util.log("[red:comms] server error : "+err.toString());
|
||||
});
|
||||
|
||||
lastSentTime = Date.now();
|
||||
|
||||
heartbeatTimer = setInterval(function() {
|
||||
var now = Date.now();
|
||||
if (now-lastSentTime > 15000) {
|
||||
lastSentTime = now;
|
||||
publish("hb",lastSentTime);
|
||||
}
|
||||
}, 15000);
|
||||
}
|
||||
|
||||
function publish(topic,data) {
|
||||
var msg = JSON.stringify({topic:topic,data:data});
|
||||
activeConnections.forEach(function(conn) {
|
||||
try {
|
||||
conn.send(msg);
|
||||
} catch(err) {
|
||||
util.log("[red:comms] send error : "+err.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
init:init,
|
||||
start:start,
|
||||
publish:publish,
|
||||
}
|
@ -18,6 +18,7 @@ var events = require("./events");
|
||||
var server = require("./server");
|
||||
var nodes = require("./nodes");
|
||||
var library = require("./library");
|
||||
var comms = require("./comms");
|
||||
var log = require("./log");
|
||||
var fs = require("fs");
|
||||
var settings = null;
|
||||
@ -50,6 +51,7 @@ var RED = {
|
||||
stop: server.stop,
|
||||
nodes: nodes,
|
||||
library: library,
|
||||
comms: comms,
|
||||
events: events,
|
||||
log: log
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ var when = require('when');
|
||||
|
||||
var createUI = require("./ui");
|
||||
var redNodes = require("./nodes");
|
||||
var comms = require("./comms");
|
||||
|
||||
var app = null;
|
||||
var nodeApp = null;
|
||||
@ -30,6 +31,7 @@ var storage = null;
|
||||
function createServer(_server,_settings) {
|
||||
server = _server;
|
||||
settings = _settings;
|
||||
comms.init(_server,_settings);
|
||||
storage = require("./storage");
|
||||
app = createUI(settings);
|
||||
nodeApp = express();
|
||||
@ -87,6 +89,7 @@ function start() {
|
||||
|
||||
redNodes.loadFlows();
|
||||
});
|
||||
comms.start();
|
||||
});
|
||||
|
||||
return defer.promise;
|
||||
|
Loading…
Reference in New Issue
Block a user