From f10ea363f0b7752d7bff4973750c4ca38ad5fbeb Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 20 Oct 2016 10:25:57 -0400 Subject: [PATCH 1/4] add dynamic sized canvas --- websocket-ui/index.html | 4 +--- websocket-ui/ui.js | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/websocket-ui/index.html b/websocket-ui/index.html index d944417..2fd2ab6 100644 --- a/websocket-ui/index.html +++ b/websocket-ui/index.html @@ -5,9 +5,7 @@ -
-
- + diff --git a/websocket-ui/ui.js b/websocket-ui/ui.js index 72ce56f..068f459 100644 --- a/websocket-ui/ui.js +++ b/websocket-ui/ui.js @@ -56,18 +56,25 @@ ws.onmessage = function(ev) { var draw = c.getContext("2d"); -draw.font = "10px monospace"; - setInterval(function() { - draw.clearRect(0, 0, c.width, c.height); - + draw.canvas.width = window.innerWidth - 100; + draw.canvas.height = window.innerHeight - 100; + draw.font = "10px monospace"; + draw.clearRect(0, 0, c.width, c.height); var n = nodes.length; var centerx = c.width / 2; var centery = c.height / 2; - var outer_r = (n * 5); + var mult = Math.log(nodes.length) + 0.5; + + var outer_r = (n * mult); + if(outer_r > c.width || outer_r > c.height) { + var smaller = c.height; + if(c.width < smaller) smaller = c.width; + outer_r = smaller - 20; + } var inner_r = outer_r / 2; draw.beginPath(); @@ -112,8 +119,10 @@ setInterval(function() { draw.beginPath(); var txt = ident.substr(0, 6); draw.fillText(txt, x2-5, y2-5); - txt += "| "+leftpad(nodes[ident].recv+" msg/s in", 15)+ " | "+leftpad(nodes[ident].send+" msg/s out", 15)+" |"; - draw.fillText(txt, 100, 20 + (i*10)); + if(i * 10 < c.height) { + txt += "| "+leftpad(nodes[ident].recv+" msg/s in", 15)+ " | "+leftpad(nodes[ident].send+" msg/s out", 15)+" |"; + draw.fillText(txt, 100, 20 + (i*10)); + } draw.moveTo(x0, y0); draw.strokeStyle = "#dfa"; From 3913ed3d303a4e3684f0648028b14d503e6d0dc8 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 20 Oct 2016 12:14:59 -0400 Subject: [PATCH 2/4] update ui for new events --- websocket-ui/index.html | 4 +++- websocket-ui/ui.js | 47 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/websocket-ui/index.html b/websocket-ui/index.html index 2fd2ab6..ecec3e6 100644 --- a/websocket-ui/index.html +++ b/websocket-ui/index.html @@ -5,7 +5,9 @@ - +
+    
+ diff --git a/websocket-ui/ui.js b/websocket-ui/ui.js index 068f459..ca72033 100644 --- a/websocket-ui/ui.js +++ b/websocket-ui/ui.js @@ -1,6 +1,6 @@ - +var l = document.getElementById("log"); var c = document.getElementById("main"); var nodes = { length: 0, @@ -37,8 +37,37 @@ function nodeRecv(ident, n) { nodes[ident].recv += parseInt(n); } +var tunnels = { + length : 0 +}; -var ws = new WebSocket("ws://127.0.0.1:7665/"); +function tunnelBuild(peers, tid, inbound) { + logit("building tunnel "+tid); +} + +function tunnelLatency(tid, latency) { + logit("tunnel "+tid+" latency "+latency+"ms"); +} + +function tunnelState(tid, state) { + logit("tunnel "+tid+" entered state "+state); +} + +function tunnelCreated(tid) { + logit("tunnel "+tid+" was created"); +} + +function logit(msg) { + console.log(msg); + var t = document.createTextNode(msg); + var e = document.createElement("div"); + e.appendChild(t); + l.appendChild(e); + while(l.children.length > 50) + l.removeChild(l.children[0]); +} + +var ws = new WebSocket("ws://127.0.0.1:7666/"); ws.onmessage = function(ev) { var j = JSON.parse(ev.data); if (j) { @@ -50,6 +79,16 @@ ws.onmessage = function(ev) { nodeSend(j.ident, j.number); } else if (j.type == "transport.recvmsg") { nodeRecv(j.ident, j.number); + } else if (j.type == "tunnel.build") { + tunnelBuild(j.value, j.tid, j.inbound); + } else if (j.type == "tunnel.latency") { + tunnelLatency(j.tid, j.value); + } else if (j.type == "tunnel.state") { + tunnelState(j.tid, j.value); + } else if (t.type == "tunnels.created") { + tunnelCreated(j.tid); + } else { + logit("message: "+j.type); } } }; @@ -67,9 +106,9 @@ setInterval(function() { var centerx = c.width / 2; var centery = c.height / 2; - var mult = Math.log(nodes.length) + 0.5; + var mult = Math.log(10 + nodes.length) + 0.5; - var outer_r = (n * mult); + var outer_r = ((10 + n) * mult); if(outer_r > c.width || outer_r > c.height) { var smaller = c.height; if(c.width < smaller) smaller = c.width; From 79ab7b80ca66e7d051929edcdb0003c4fb2c44c8 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 20 Oct 2016 15:12:06 -0400 Subject: [PATCH 3/4] more updates --- websocket-ui/ui.js | 229 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 192 insertions(+), 37 deletions(-) diff --git a/websocket-ui/ui.js b/websocket-ui/ui.js index ca72033..e9cc2b9 100644 --- a/websocket-ui/ui.js +++ b/websocket-ui/ui.js @@ -1,10 +1,14 @@ - +var url = "ws://127.0.0.1:7666"; var l = document.getElementById("log"); var c = document.getElementById("main"); var nodes = { length: 0, }; +var in_traffic = 0; +var out_traffic = 0; +var tick = 0; + function nodeConnected(ident) { if (nodes[ident]) { return; @@ -37,20 +41,87 @@ function nodeRecv(ident, n) { nodes[ident].recv += parseInt(n); } + +var tpeers = {}; + var tunnels = { length : 0 }; +function ensureTunnel(tid) { + if(!tunnels[tid]) { + tunnels[tid] = { + latency : -1, + color: "#ddd", + }; + tunnels.length ++; + } +} + function tunnelBuild(peers, tid, inbound) { - logit("building tunnel "+tid); + logit("Tunnel "+tid+" build started"); + ensureTunnel(tid); + tunnels[tid].peers = peers.split(":"); + tunnels[tid].inbound = inbound; + tunnels[tid].state = "building"; } function tunnelLatency(tid, latency) { - logit("tunnel "+tid+" latency "+latency+"ms"); + // logit("tunnel "+tid+" latency "+latency+"ms"); + if (!tunnels[tid]) return; + tunnels[tid].latency = latency; } +function tunnelEstablished(tid) { + if(!tunnels[tid]) return; + logit("Tunnel " + tid + " is healthy"); + tunnels[tid].state = "healthy"; + tunnels[tid].color = "#1d1"; +} + +function tunnelBuildFailed(tid) { + if(!tunnels[tid]) return; + logit("Tunnel " + tid + " failed to build"); + delete tunnels[tid]; + tunnels.length --; +} + +function tunnelTestFailed(tid) { + if(!tunnels[tid]) return; + logit("Tunnel " + tid + " has failed tunnel test"); + tunnels[tid].state = "stuck"; + tunnels[tid].color = "orange"; +} + +function tunnelFailed(tid) { + if(!tunnels[tid]) return; + logit("Tunnel " + tid + " has failed"); + tunnels[tid].state = "failed"; + tunnels[tid].color = "red"; +} + +function tunnelExpiring(tid) { + if(!tunnels[tid]) return; + logit("Tunnel " + tid + " is expired"); + delete tunnels[tid]; + tunnels.length--; +} + + function tunnelState(tid, state) { - logit("tunnel "+tid+" entered state "+state); + if (state == "3") { + tunnelEstablished(tid); + } else if (state == "2" ) { + tunnelBuildFailed(tid); + } else if (state == "4" ) { + tunnelTestFailed(tid); + } else if (state == "5" ) { + tunnelFailed(tid); + } else if (state == "6" ) { + tunnelExpiring(tid); + } else { + logit("tunnel "+tid+" state "+state); + } } function tunnelCreated(tid) { @@ -67,10 +138,15 @@ function logit(msg) { l.removeChild(l.children[0]); } -var ws = new WebSocket("ws://127.0.0.1:7666/"); +var ws = new WebSocket(url); +ws.onclose = function (ev) { + nodes = { length: 0 }; + tpeers = { length: 0 }; +} ws.onmessage = function(ev) { var j = JSON.parse(ev.data); if (j) { + console.log(j); if(j.type == "transport.connected") { nodeConnected(j.ident); } else if (j.type == "transport.disconnected") { @@ -85,22 +161,104 @@ ws.onmessage = function(ev) { tunnelLatency(j.tid, j.value); } else if (j.type == "tunnel.state") { tunnelState(j.tid, j.value); - } else if (t.type == "tunnels.created") { + } else if (j.type == "tunnels.created") { tunnelCreated(j.tid); + } else if (j.type == "tunnels.expired") { + tunnelExpiring(j.tid); } else { logit("message: "+j.type); } } }; -var draw = c.getContext("2d"); +function getPeer(h, us) { + if (tpeers[h]) { + return tpeers[h]; + } + console.log("make peer "+h); + + var p = { + x: Math.random(), + y: Math.random(), + name: h, + }; + if (us) { + p.x = 0.5; + p.y = 0.5; + } else { + while (Math.abs(p.x - 0.5) <= 0.1 ) { + p.x = Math.random(); + } + while (Math.abs(p.y - 0.5) <= 0.1 ) { + p.y = Math.random(); + } + } + tpeers[h] = p; + return p; +} +function drawPeer(p) { + draw.beginPath(); + draw.lineWidth = 1; + draw.fillStyle = "white"; + draw.strokeStyle = "white"; + draw.arc(p.x * c.width, p.y * c.height, 20, 0, 2* Math.PI); + draw.stroke(); + draw.fillText(p.name.substr(0,6), p.x * c.width, p.y * c.height); +} + + +function getTraffic(node) { + if (!node) return 1; + return 1.0 + ( (node.send + node.recv + 1.0) / 5.0) ; +} +var draw = c.getContext("2d"); +var ticks = 0; +// draw setInterval(function() { draw.canvas.width = window.innerWidth - 100; draw.canvas.height = window.innerHeight - 100; draw.font = "10px monospace"; draw.clearRect(0, 0, c.width, c.height); + + // draw tunnels + + var e = []; + + for (var tid in tunnels) { + if(tid == "length") continue; + var t = tunnels[tid]; + var us = getPeer(t.peers[0], true); + var traff = getTraffic(nodes[t.peers[1]]); + e.push([us, getPeer(t.peers[1]), t.color, traff]); + for (var idx = 1 ; idx + 1 < t.peers.length; idx ++ ) { + var cur = getPeer(t.peers[idx]); + var next = getPeer(t.peers[idx+1]); + if(cur && next) + e.push([cur, next, t.color, traff]); + else + console.log(cur, next); + } + } + + for ( var h in tpeers ) { + drawPeer(getPeer(h)); + } + + for ( var ed in e ) { + var edge = e[ed]; + draw.beginPath(); + draw.strokeStyle = edge[2]; + draw.lineWidth = edge[3]; + draw.moveTo(edge[0].x * c.width, edge[0].y * c.height); + draw.lineTo(edge[1].x * c.width, edge[1].y * c.height); + draw.stroke(); + + } + + // draw nodes + var n = nodes.length; var centerx = c.width / 2; @@ -133,35 +291,36 @@ setInterval(function() { } idents = idents.sort(); - var in_traffic = 0; - var out_traffic = 0; for (var i = 0; i < idents.length; i++) { var ident = idents[i]; rad += ( Math.PI * 2 ) / nodes.length; - in_traffic += nodes[ident].recv; - out_traffic += nodes[ident].send; + in_traffic += nodes[ident].recv / 10.0 ; + out_traffic += nodes[ident].send / 10.0; - var send = nodes[ident].send * 5; - var recv = nodes[ident].recv * 5; + var send = (nodes[ident].send ) * 5; + var recv = (nodes[ident].recv ) * 5; + var traff = (getTraffic(nodes[ident]) - 1) * 5; + var x0 = (Math.cos(rad) * inner_r) + centerx; var y0 = (Math.sin(rad) * inner_r) + centery; - var x1 = (Math.cos(rad) * (inner_r + send )) + centerx; - var y1 = (Math.sin(rad) * (inner_r + send )) + centery; - var bigger = send; - if (recv > bigger) bigger = recv; - var x2 = (Math.cos(rad) * (inner_r + bigger )) + centerx; - var y2 = (Math.sin(rad) * (inner_r + bigger )) + centery; - + var x1 = (Math.cos(rad) * (inner_r + traff )) + centerx; + var y1 = (Math.sin(rad) * (inner_r + traff )) + centery; + draw.fillStyle = "white"; draw.beginPath(); var txt = ident.substr(0, 6); - draw.fillText(txt, x2-5, y2-5); + draw.fillText(txt, x1-5, y1-5); if(i * 10 < c.height) { txt += "| "+leftpad(nodes[ident].recv+" msg/s in", 15)+ " | "+leftpad(nodes[ident].send+" msg/s out", 15)+" |"; draw.fillText(txt, 100, 20 + (i*10)); } + if( tick % 10 == 0) { + + nodes[ident].recv = 0; + nodes[ident].send = 0; + } draw.moveTo(x0, y0); draw.strokeStyle = "#dfa"; @@ -170,16 +329,6 @@ setInterval(function() { draw.lineTo(x1, y1); draw.lineWidth = 8; draw.stroke(); - - x1 = (Math.cos(rad) * (inner_r + recv )) + centerx; - y1 = (Math.sin(rad) * (inner_r + recv )) + centery; - - draw.beginPath(); - draw.strokeStyle = "#fda"; - draw.moveTo(x0, y0); - draw.lineTo(x1, y1); - draw.lineWidth = 10; - draw.stroke(); /* if(( 40 + idx ) < c.height) { var send = nodes[ident].send * 10; @@ -202,11 +351,17 @@ setInterval(function() { idx += 40; } */ - nodes[ident].send = 0; - nodes[ident].recv = 0; + } draw.fillStyle = "white"; - draw.fillText("Active Peers | " +leftpad(" "+ nodes.length, 10), 500, 25); - draw.fillText("In Traffic | "+leftpad(" "+in_traffic+" msg/s", 10), 500, 35); - draw.fillText("Out Traffic | "+leftpad(" "+out_traffic+" msg/s", 10), 500, 45); -}, 1000); + draw.fillText("Tracked Peers | " +leftpad(" "+ nodes.length, 10), 500, 25); + draw.fillText("Tracked Tunnels | " +leftpad(" "+ tunnels.length, 10), 500, 35); + draw.fillText("In Traffic | "+leftpad(" "+Math.ceil(in_traffic)+" msg/s", 10), 500, 45); + draw.fillText("Out Traffic | "+leftpad(" "+Math.ceil(out_traffic)+" msg/s", 10), 500, 55); + + if (tick % 10 == 0) { + in_traffic = 0; + out_traffic = 0; + } + tick ++; +}, 100); From 6e7d8c3eb17a810fa91ef44ec3533d711d9c778f Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 20 Oct 2016 16:12:03 -0400 Subject: [PATCH 4/4] fixes --- websocket-ui/ui.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/websocket-ui/ui.js b/websocket-ui/ui.js index e9cc2b9..c076dbe 100644 --- a/websocket-ui/ui.js +++ b/websocket-ui/ui.js @@ -210,7 +210,7 @@ function drawPeer(p) { function getTraffic(node) { if (!node) return 1; - return 1.0 + ( (node.send + node.recv + 1.0) / 5.0) ; + return 1.0 + ( (node.send + node.recv + 1.0) / 1.5) ; } var draw = c.getContext("2d"); var ticks = 0; @@ -316,11 +316,8 @@ setInterval(function() { txt += "| "+leftpad(nodes[ident].recv+" msg/s in", 15)+ " | "+leftpad(nodes[ident].send+" msg/s out", 15)+" |"; draw.fillText(txt, 100, 20 + (i*10)); } - if( tick % 10 == 0) { - - nodes[ident].recv = 0; - nodes[ident].send = 0; - } + nodes[ident].recv = 0; + nodes[ident].send = 0; draw.moveTo(x0, y0); draw.strokeStyle = "#dfa";