Skip to content

Commit 16f8673

Browse files
committed
Add comms module
1 parent e6794a0 commit 16f8673

7 files changed

Lines changed: 203 additions & 132 deletions

File tree

nodes/core/core/58-debug.html

Lines changed: 45 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
}
9292
});
9393

94-
var a = function() {
94+
(function() {
9595
var content = document.createElement("div");
9696
content.id = "tab-debug";
9797

@@ -114,84 +114,56 @@
114114

115115
var sbc = document.getElementById("debug-content");
116116

117-
var errornotification = null;
118-
119117
var messageCount = 0;
120118

121-
122-
function debugConnect() {
123-
//console.log("debug ws connecting");
124-
var path = location.hostname+":"+location.port+document.location.pathname;
125-
path = path+(path.slice(-1) == "/"?"":"/")+"debug/ws";
126-
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
127-
var ws = new WebSocket(path);
128-
ws.onopen = function() {
129-
if (errornotification) {
130-
errornotification.close();
131-
errornotification = null;
132-
}
133-
//console.log("debug ws connected");
134-
}
135-
ws.onmessage = function(event) {
136-
var o = JSON.parse(event.data);
137-
if (o.heartbeat) {
138-
return;
119+
var handleDebugMessage = function(t,o) {
120+
var msg = document.createElement("div");
121+
msg.onmouseover = function() {
122+
msg.style.borderRightColor = "#999";
123+
var n = RED.nodes.node(o.id);
124+
if (n) {
125+
n.highlighted = true;
126+
n.dirty = true;
139127
}
140-
//console.log(msg);
141-
var msg = document.createElement("div");
142-
msg.onmouseover = function() {
143-
msg.style.borderRightColor = "#999";
144-
var n = RED.nodes.node(o.id);
145-
if (n) {
146-
n.highlighted = true;
147-
n.dirty = true;
148-
}
149-
RED.view.redraw();
150-
};
151-
msg.onmouseout = function() {
152-
msg.style.borderRightColor = "";
153-
var n = RED.nodes.node(o.id);
154-
if (n) {
155-
n.highlighted = false;
156-
n.dirty = true;
157-
}
158-
RED.view.redraw();
159-
};
160-
msg.onclick = function() {
161-
var node = RED.nodes.node(o.id);
162-
if (node) {
163-
RED.view.showWorkspace(node.z);
164-
}
165-
166-
};
167-
var name = (o.name?o.name:o.id).toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
168-
var topic = (o.topic||"").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
169-
var payload = (o.msg||"").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
170-
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'')
171-
msg.innerHTML = '<span class="debug-message-date">'+getTimestamp()+'</span>'+
172-
'<span class="debug-message-name">['+name+']</span>'+
173-
(o.topic?'<span class="debug-message-topic">'+topic+'</span>':'')+
174-
'<span class="debug-message-payload">'+payload+'</span>';
175-
var atBottom = (sbc.scrollHeight-messages.offsetHeight-sbc.scrollTop) < 5;
176-
messageCount++;
177-
$(messages).append(msg);
178-
179-
if (messageCount > 200) {
180-
$("#debug-content .debug-message:first").remove();
181-
messageCount--;
182-
}
183-
if (atBottom) {
184-
$(sbc).scrollTop(sbc.scrollHeight);
128+
RED.view.redraw();
129+
};
130+
msg.onmouseout = function() {
131+
msg.style.borderRightColor = "";
132+
var n = RED.nodes.node(o.id);
133+
if (n) {
134+
n.highlighted = false;
135+
n.dirty = true;
185136
}
137+
RED.view.redraw();
186138
};
187-
ws.onclose = function() {
188-
if (errornotification == null) {
189-
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true);
139+
msg.onclick = function() {
140+
var node = RED.nodes.node(o.id);
141+
if (node) {
142+
RED.view.showWorkspace(node.z);
190143
}
191-
setTimeout(debugConnect,1000);
144+
145+
};
146+
var name = (o.name?o.name:o.id).toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
147+
var topic = (o.topic||"").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
148+
var payload = (o.msg||"").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
149+
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'')
150+
msg.innerHTML = '<span class="debug-message-date">'+getTimestamp()+'</span>'+
151+
'<span class="debug-message-name">['+name+']</span>'+
152+
(o.topic?'<span class="debug-message-topic">'+topic+'</span>':'')+
153+
'<span class="debug-message-payload">'+payload+'</span>';
154+
var atBottom = (sbc.scrollHeight-messages.offsetHeight-sbc.scrollTop) < 5;
155+
messageCount++;
156+
$(messages).append(msg);
157+
158+
if (messageCount > 200) {
159+
$("#debug-content .debug-message:first").remove();
160+
messageCount--;
192161
}
193-
}
194-
debugConnect();
162+
if (atBottom) {
163+
$(sbc).scrollTop(sbc.scrollHeight);
164+
}
165+
};
166+
RED.comms.subscribe("debug",handleDebugMessage);
195167

196168
$("#debug-tab-clear").click(function() {
197169
$(".debug-message").remove();
@@ -203,7 +175,7 @@
203175
RED.view.redraw();
204176
});
205177

206-
}();
178+
})();
207179
</script>
208180

209181
<style>

nodes/core/core/58-debug.js

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -51,35 +51,15 @@ module.exports = function(RED) {
5151
if (typeof msg.payload == "undefined") { msg.payload = "(undefined)"; }
5252
if (msg.payload instanceof Buffer) { msg.payload = "(Buffer) "+msg.payload.toString('hex'); }
5353
if (this.active) {
54-
DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path});
54+
sendDebug({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path});
5555
}
5656
}
5757
});
5858
}
59-
60-
var lastSentTime = (new Date()).getTime();
61-
62-
setInterval(function() {
63-
var now = (new Date()).getTime();
64-
if (now-lastSentTime > 15000) {
65-
lastSentTime = now;
66-
for (var i in DebugNode.activeConnections) {
67-
var ws = DebugNode.activeConnections[i];
68-
try {
69-
var p = JSON.stringify({heartbeat:lastSentTime});
70-
ws.send(p);
71-
} catch(err) {
72-
util.log("[debug] ws heartbeat error : "+err);
73-
}
74-
}
75-
}
76-
}, 15000);
77-
78-
79-
59+
8060
RED.nodes.registerType("debug",DebugNode);
8161

82-
DebugNode.send = function(msg) {
62+
function sendDebug(msg) {
8363
if (msg.msg instanceof Error) {
8464
msg.msg = msg.msg.toString();
8565
} else if (typeof msg.msg === 'object') {
@@ -106,47 +86,13 @@ module.exports = function(RED) {
10686
msg.msg = msg.msg.substr(0,debuglength) +" ....";
10787
}
10888

109-
for (var i in DebugNode.activeConnections) {
110-
var ws = DebugNode.activeConnections[i];
111-
try {
112-
var p = JSON.stringify(msg);
113-
ws.send(p);
114-
} catch(err) {
115-
util.log("[debug] ws error : "+err);
116-
}
117-
}
118-
lastSentTime = (new Date()).getTime();
89+
RED.comms.publish("debug",msg);
11990
}
12091

121-
DebugNode.activeConnections = [];
122-
123-
var path = RED.settings.httpAdminRoot || "/";
124-
path = path + (path.slice(-1) == "/" ? "":"/") + "debug/ws";
125-
126-
DebugNode.wsServer = new ws.Server({server:RED.server,path:path});
127-
DebugNode.wsServer.on('connection',function(ws) {
128-
DebugNode.activeConnections.push(ws);
129-
ws.on('close',function() {
130-
for (var i in DebugNode.activeConnections) {
131-
if (DebugNode.activeConnections[i] === ws) {
132-
DebugNode.activeConnections.splice(i,1);
133-
break;
134-
}
135-
}
136-
});
137-
ws.on('error', function(err) {
138-
util.log("[debug] ws error : "+err);
139-
});
140-
});
141-
142-
DebugNode.wsServer.on('error', function(err) {
143-
util.log("[debug] ws server error : "+err);
144-
});
145-
14692
DebugNode.logHandler = new events.EventEmitter();
14793
DebugNode.logHandler.on("log",function(msg) {
14894
if (msg.level == "warn" || msg.level == "error") {
149-
DebugNode.send(msg);
95+
sendDebug(msg);
15096
}
15197
});
15298
RED.log.addHandler(DebugNode.logHandler);

public/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,5 +317,6 @@ <h5 id="node-help-label">Keyboard Shortcuts <span style="float: right;"><a href=
317317
<script src="red/ui/editor.js"></script>
318318
<script src="red/ui/library.js"></script>
319319
<script src="red/ui/notifications.js"></script>
320+
<script src="red/comms.js"></script>
320321
</body>
321322
</html>

public/red/comms.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright 2014 IBM Corp.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
17+
RED.comms = function() {
18+
19+
var errornotification = null;
20+
var subscriptions = {};
21+
22+
function connectWS() {
23+
var path = location.hostname+":"+location.port+document.location.pathname;
24+
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
25+
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
26+
var ws = new WebSocket(path);
27+
ws.onopen = function() {
28+
if (errornotification) {
29+
errornotification.close();
30+
errornotification = null;
31+
}
32+
}
33+
ws.onmessage = function(event) {
34+
var msg = JSON.parse(event.data);
35+
var subscribers = subscriptions[msg.topic];
36+
if (subscribers) {
37+
for (var i=0;i<subscribers.length;i++) {
38+
subscribers[i](msg.topic,msg.data);
39+
}
40+
}
41+
};
42+
ws.onclose = function() {
43+
if (errornotification == null) {
44+
errornotification = RED.notify("<b>Error</b>: Lost connection to server","error",true);
45+
}
46+
setTimeout(connectWS,1000);
47+
}
48+
}
49+
connectWS();
50+
51+
function subscribe(topic,callback) {
52+
if (subscriptions[topic] == null) {
53+
subscriptions[topic] = [];
54+
}
55+
subscriptions[topic].push(callback);
56+
}
57+
58+
return {
59+
subscribe: subscribe
60+
}
61+
}();

red/comms.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright 2014 IBM Corp.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
17+
var ws = require("ws");
18+
var util = require("util");
19+
20+
var server;
21+
var settings;
22+
23+
var wsServer;
24+
var activeConnections = [];
25+
26+
var heartbeatTimer;
27+
var lastSentTime;
28+
29+
30+
function init(_server,_settings) {
31+
server = _server;
32+
settings = _settings;
33+
}
34+
35+
function start() {
36+
var path = settings.httpAdminRoot || "/";
37+
path = path + (path.slice(-1) == "/" ? "":"/") + "comms";
38+
wsServer = new ws.Server({server:server,path:path});
39+
40+
wsServer.on('connection',function(ws) {
41+
activeConnections.push(ws);
42+
ws.on('close',function() {
43+
for (var i=0;i<activeConnections.length;i++) {
44+
if (activeConnections[i] === ws) {
45+
activeConnections.splice(i,1);
46+
break;
47+
}
48+
}
49+
});
50+
ws.on('error', function(err) {
51+
util.log("[red:comms] error : "+err.toString());
52+
});
53+
});
54+
55+
wsServer.on('error', function(err) {
56+
util.log("[red:comms] server error : "+err.toString());
57+
});
58+
59+
lastSentTime = Date.now();
60+
61+
heartbeatTimer = setInterval(function() {
62+
var now = Date.now();
63+
if (now-lastSentTime > 15000) {
64+
lastSentTime = now;
65+
publish("hb",lastSentTime);
66+
}
67+
}, 15000);
68+
}
69+
70+
function publish(topic,data) {
71+
var msg = JSON.stringify({topic:topic,data:data});
72+
activeConnections.forEach(function(conn) {
73+
try {
74+
conn.send(msg);
75+
} catch(err) {
76+
util.log("[red:comms] send error : "+err.toString());
77+
}
78+
});
79+
}
80+
81+
82+
module.exports = {
83+
init:init,
84+
start:start,
85+
publish:publish,
86+
}

0 commit comments

Comments
 (0)