diff --git a/app.js b/app.js index 582914e..8418a0f 100644 --- a/app.js +++ b/app.js @@ -30,6 +30,8 @@ var client = new Primus(server, { parser: 'JSON' }); +var clientLatency = 0; + client.use('emit', require('primus-emit')); api.on('connection', function(spark) { @@ -115,8 +117,18 @@ client.on('connection', function(spark) { spark.emit('init', {nodes: Nodes.all()}); }); + + spark.on('client-pong', function(data) { + var latency = Math.ceil(((new Date()).getTime() - clientLatency)/2); + spark.emit('client-latency', { latency: latency }); + }); }); +var latencyTimeout = setInterval(function(){ + clientLatency = (new Date()).getTime(); + client.write({action: 'client-ping'}); +}, 5000); + // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); diff --git a/public/css/style.css b/public/css/style.css index b86f22d..8d7816c 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -58,6 +58,10 @@ body { .big-info span.small-title, .big-info div.small-title-miner { display: block; +} + +span.small-title, +div.small-title-miner { font-weight: 700; font-size: 14px; line-height: 20px; @@ -116,6 +120,18 @@ body { float: left; -webkit-border-radius: 1px; border-radius: 1px; + opacity: .8; +} + +.page-latency { + position: absolute; + top: 400px; + left: 15px; +} + +.page-latency .small-title { + letter-spacing: 0px; + opacity: .8; } .jqstooltip { diff --git a/public/js/controllers.js b/public/js/controllers.js index 50578ff..0886664 100644 --- a/public/js/controllers.js +++ b/public/js/controllers.js @@ -25,6 +25,8 @@ function StatsCtrl($scope, $filter, socket, _, toastr) { $scope.nodes = []; $scope.map = []; + $scope.latency = 0; + $scope.predicate = 'info.name'; $scope.reverse = false; @@ -76,6 +78,11 @@ function StatsCtrl($scope, $filter, socket, _, toastr) { socketAction("init", data.nodes); }); + socket.on('client-latency', function(data) + { + $scope.latency = data.latency; + }) + function socketAction(action, data) { console.log('Action: ', action); @@ -111,6 +118,10 @@ function StatsCtrl($scope, $filter, socket, _, toastr) { case "latency": $scope.nodes[findIndex({id: data.id})].stats.latency = data.latency; break; + + case "client-ping": + socket.emit('client-pong'); + break; } updateStats(); diff --git a/views/index.jade b/views/index.jade index 868ca0d..fed7cb5 100644 --- a/views/index.jade +++ b/views/index.jade @@ -2,6 +2,9 @@ extends layout block content div.container-fluid(ng-controller='StatsCtrl') + div.page-latency + span.small-title page latency:#[ ] + span(class="{{ {active: true, latency: latency} | latencyClass }}") {{latency}} ms div.row(ng-cloak) div.col-xs-2.stat-holder div.big-info.nodesactive(class="{{ nodesActive | nodesActiveClass : nodesTotal }}") @@ -119,7 +122,7 @@ block content i.icon-network(data-toggle="tooltip", data-placement="top", title="Pending transactions", ng-click="orderTable('-stats.pending', false)") th i.icon-block(data-toggle="tooltip", data-placement="top", title="Last block", ng-click="orderTable(['-stats.block.number', 'stats.block.propagation'], false)") - th.th-blockhash   + th.th-blockhash #[ ] th i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions", ng-click="orderTable('-stats.block.transactions.length', false)") th.th-blocktime @@ -132,7 +135,7 @@ block content tr(ng-repeat='node in nodes | orderBy:predicate:reverse', class="{{ node.stats | mainClass : bestBlock }}") td(rel="{{node.id}}") span.small(data-toggle="tooltip", data-placement="top", data-original-title="{{node.geo | geoTooltip}}") {{node.info.name}} - span.small  ({{node.info.ip}}) + span.small #[ ]({{node.info.ip}}) td div.small(ng-bind-html="node.info.node | nodeVersion") //- div.small {{node.info.os}}, {{node.info.os_v}}