From f0000644b4c829edab1d448f157ef1bad2854b00 Mon Sep 17 00:00:00 2001 From: Gene Hallman Date: Sun, 24 Jan 2016 16:23:12 -0800 Subject: [PATCH 1/4] working first draft admin site --- admin/.bowerrc | 3 + admin/admin.js | 48 +- admin/bower.json | 14 + admin/index.html | 165 - admin/public/css/style.css | 28 + admin/public/js/components/charts.jsx | 92 + admin/public/js/components/dashboard.jsx | 58 + admin/public/js/components/erizo_item.jsx | 65 + admin/public/js/components/erizo_list.jsx | 21 + admin/public/js/lib/react/.bower.json | 19 + admin/public/js/lib/react/LICENSE | 31 + admin/public/js/lib/react/PATENTS | 33 + admin/public/js/lib/react/bower.json | 5 + admin/public/js/lib/react/react-dom-server.js | 42 + .../js/lib/react/react-dom-server.min.js | 12 + admin/public/js/lib/react/react-dom.js | 42 + admin/public/js/lib/react/react-dom.min.js | 12 + .../public/js/lib/react/react-with-addons.js | 20761 ++++++++++++++++ .../js/lib/react/react-with-addons.min.js | 16 + admin/public/js/lib/react/react.js | 18802 ++++++++++++++ admin/public/js/lib/react/react.min.js | 16 + .../js/lib/requirejs-react-jsx/.bower.json | 41 + .../public/js/lib/requirejs-react-jsx/LICENSE | 21 + .../requirejs-react-jsx/babel-5.8.34.min.js | 29 + .../js/lib/requirejs-react-jsx/bower.json | 30 + .../public/js/lib/requirejs-react-jsx/jsx.js | 99 + .../js/lib/requirejs-react-jsx/package.json | 25 + .../js/lib/requirejs-react-jsx/readme.md | 150 + .../public/js/lib/requirejs-text/.bower.json | 15 + admin/public/js/lib/requirejs-text/LICENSE | 58 + admin/public/js/lib/requirejs-text/README.md | 198 + admin/public/js/lib/requirejs-text/bower.json | 5 + .../public/js/lib/requirejs-text/package.json | 30 + admin/public/js/lib/requirejs-text/text.js | 391 + admin/public/js/main.js | 4 + admin/public/js/pubsub.js | 51 + admin/public/js/requirejs-config.js | 29 + admin/views/index.ejs | 12 + .../{client/src/admin.js => views/layout.ejs} | 0 admin/{test.html => views/test.ejs} | 0 erizo_controller/erizoAgent/erizoAgent.js | 10 +- erizo_controller/erizoClient/src/Stream.js | 2 +- .../erizoController/roomController.js | 6 +- erizo_controller/erizoJS/erizoJSController.js | 9 +- extras/basic_example/public/script.js | 2 +- scripts/installUbuntuDepsUnattended.sh | 2 +- 46 files changed, 41311 insertions(+), 193 deletions(-) create mode 100644 admin/.bowerrc create mode 100644 admin/bower.json delete mode 100644 admin/index.html create mode 100644 admin/public/css/style.css create mode 100644 admin/public/js/components/charts.jsx create mode 100644 admin/public/js/components/dashboard.jsx create mode 100644 admin/public/js/components/erizo_item.jsx create mode 100644 admin/public/js/components/erizo_list.jsx create mode 100644 admin/public/js/lib/react/.bower.json create mode 100644 admin/public/js/lib/react/LICENSE create mode 100644 admin/public/js/lib/react/PATENTS create mode 100644 admin/public/js/lib/react/bower.json create mode 100644 admin/public/js/lib/react/react-dom-server.js create mode 100644 admin/public/js/lib/react/react-dom-server.min.js create mode 100644 admin/public/js/lib/react/react-dom.js create mode 100644 admin/public/js/lib/react/react-dom.min.js create mode 100644 admin/public/js/lib/react/react-with-addons.js create mode 100644 admin/public/js/lib/react/react-with-addons.min.js create mode 100644 admin/public/js/lib/react/react.js create mode 100644 admin/public/js/lib/react/react.min.js create mode 100644 admin/public/js/lib/requirejs-react-jsx/.bower.json create mode 100644 admin/public/js/lib/requirejs-react-jsx/LICENSE create mode 100644 admin/public/js/lib/requirejs-react-jsx/babel-5.8.34.min.js create mode 100644 admin/public/js/lib/requirejs-react-jsx/bower.json create mode 100644 admin/public/js/lib/requirejs-react-jsx/jsx.js create mode 100644 admin/public/js/lib/requirejs-react-jsx/package.json create mode 100644 admin/public/js/lib/requirejs-react-jsx/readme.md create mode 100644 admin/public/js/lib/requirejs-text/.bower.json create mode 100644 admin/public/js/lib/requirejs-text/LICENSE create mode 100644 admin/public/js/lib/requirejs-text/README.md create mode 100644 admin/public/js/lib/requirejs-text/bower.json create mode 100644 admin/public/js/lib/requirejs-text/package.json create mode 100644 admin/public/js/lib/requirejs-text/text.js create mode 100644 admin/public/js/main.js create mode 100644 admin/public/js/pubsub.js create mode 100644 admin/public/js/requirejs-config.js create mode 100644 admin/views/index.ejs rename admin/{client/src/admin.js => views/layout.ejs} (100%) rename admin/{test.html => views/test.ejs} (100%) diff --git a/admin/.bowerrc b/admin/.bowerrc new file mode 100644 index 0000000000..6b8d547725 --- /dev/null +++ b/admin/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "public/js/lib" +} diff --git a/admin/admin.js b/admin/admin.js index d7e70c28c7..6d05987213 100644 --- a/admin/admin.js +++ b/admin/admin.js @@ -4,36 +4,62 @@ var config = require('./../licode_config'); GLOBAL.config = config || {}; var amqper = require('./../erizo_controller/common/amqper.js') -var app = require('express')(); +var express = require('express'); +var app = express(); // var http = require('http'); var server = require('http').Server(app); var io = require('socket.io').listen(server); +var latestStats = {}; -amqper.connect(function() { - server.listen(PORT); -}); +// app.set('view options', { layout: "layout" }); + +app.use('/public', express.static('public')); app.get('/', function (req, res) { - res.sendFile(__dirname + '/index.html'); + res.render('index.ejs'); }); app.get('/test', function (req, res) { - res.sendFile(__dirname + '/test.html'); + res.render('test.ejs'); }); -app.get('/admin.js', function(req, res) { - res.sendFile(__dirname + '/client/src/admin.js'); -}); +// app.get('/admin.js', function(req, res) { +// res.sendFile(__dirname + '/client/src/admin.js'); +// }); io.on('connection', function (socket) { - socket.on('call', function (req) { + socket.on('broadcast', function (req) { + console.log("broadcast - req:", req); amqper.broadcast(req.type, {method: req.method, args: req.args || []}, function (resp) { - console.log(arguments); + console.log("broadcast - resp:", arguments); resp.req = req; socket.emit('result', resp); }); }); + socket.on('call', function (req) { + console.log("call - req:", req.type); + amqper.callRpc(req.type, req.method, (req.args || []), {"callback": function (resp) { + console.log("call - resp:", arguments); + if (resp == "timeout") { + resp = {type: "timeout"}; + } + resp.req = req; + socket.emit('result', resp); + }}); + }); + + socket.on('subscribe', function (req) { + console.log("subscribe - req:", req.type); + amqper.bind_broadcast(req.type, function(resp, err) { + console.log("subscribe - resp:", resp); + resp.req = req; + socket.emit('subscription', resp); + }); + }); }); +amqper.connect(function() { + server.listen(PORT); +}); diff --git a/admin/bower.json b/admin/bower.json new file mode 100644 index 0000000000..08dbdb3e3c --- /dev/null +++ b/admin/bower.json @@ -0,0 +1,14 @@ +{ + "name": "admin", + "private": true, + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "requirejs-react-jsx": "~1.0.2" + } +} diff --git a/admin/index.html b/admin/index.html deleted file mode 100644 index 353a7fcb8f..0000000000 --- a/admin/index.html +++ /dev/null @@ -1,165 +0,0 @@ - - - Licode Admin - - - - - - - - - - -
-
- - - - - diff --git a/admin/public/css/style.css b/admin/public/css/style.css new file mode 100644 index 0000000000..3087d05523 --- /dev/null +++ b/admin/public/css/style.css @@ -0,0 +1,28 @@ +.x.axis line { + shape-rendering: auto; +} + +.line { + fill: none; + stroke: #000; + stroke-width: 1.5px; +} +table { + margin-top:10px; + margin-bottom:10px; +} +td { + padding:0px; + padding-top:10px; + margin-top:10px; + width: 60px; + text-align:center; +} +td.header { + width: 90px; + text-align:left; +} + +#graphHolder svg { + overflow: visible; +} diff --git a/admin/public/js/components/charts.jsx b/admin/public/js/components/charts.jsx new file mode 100644 index 0000000000..a5e9ad4772 --- /dev/null +++ b/admin/public/js/components/charts.jsx @@ -0,0 +1,92 @@ +define(['d3', 'react'], function(d3, React) { + + var margin = {top: 5, right: 0, bottom: 5, left: 100}, + width = 450 - margin.right, + height = 90 - margin.top - margin.bottom; + + + return React.createClass({ + displayName: 'MovingLineChart', + + getInitialState: function() { + + var that = this; + this.x = d3.scale.linear().domain(this.props.xdomain).range([0, width]); + this.y = d3.scale.linear().domain(this.props.ydomain).range([height, 0]); + this.line = d3.svg.line() + .interpolate(this.props.interpolation) + .x(function(d, i) { return that.x(i); }) + .y(function(d, i) { return that.y(d); }); + + var data = d3.range(this.props.xdomain[1] - this.props.xdomain[0]).map(function() { return that.props.value; }); + + return { + maxVal: parseFloat(this.props.ydomain[0]), + minVal: parseFloat(this.props.ydomain[1]), + data: data, + lineData: "" + }; + + }, + + getDefaultProps: function() { + return { + title: "Chart", + ydomain: [0, 100], + xdomain: [1, 300], + interpolation: "basis", + value: 0 + } + }, + + render: function() { + + return ( + + + + + + +
{this.props.title} + + + + + + + + {this.props.value}{this.state.minVal}{this.state.maxVal}
+ ); + }, + + updateGraphData: function() { + var newPoint = this.props.value; + var newData = this.state.data.slice(1).concat([newPoint]); + var newState = { data: newData, lineData: this.line(newData), source:"internal"}; + + if (newPoint > this.state.maxVal) { + newState.maxVal = newPoint; + } else if (newPoint < this.state.minVal) { + newState.minVal = newPoint; + } + this.setState(newState); + }, + + componentDidMount: function() { + d3.select(this.refs.y_axis).call(d3.svg.axis().scale(this.y).ticks(5).orient("left")); + }, + + componentDidUpdate: function () { + var that = this; + // redraw the line, and then slide it to the left + d3.select(that.refs.path) + .transition() + .duration(100) + .ease("linear") + .attr("transform", "translate(" + that.x(0) + ")") + .each("end", function() { that.updateGraphData(); }); + } + + }); +}); diff --git a/admin/public/js/components/dashboard.jsx b/admin/public/js/components/dashboard.jsx new file mode 100644 index 0000000000..9fbc5ea2ae --- /dev/null +++ b/admin/public/js/components/dashboard.jsx @@ -0,0 +1,58 @@ +define(['pubsub', 'jsx!components/charts', 'react', 'jsx!components/erizo_list'], function (PubSub, MovingLineChart, React, ErizoList) { + var xdomain_length = 300; + var DATA_INTERVAL = 5000; + var latest = {cpu:0, mem:0}; + + return React.createClass({ + displayName: 'Dashboard', + + getInitialState: function() { + return { cpu:0, mem:0, erizos:[], stats: {} } + }, + + updateLicodeData: function() { + var that = this; + + PubSub.broadcast("ErizoAgent.getErizoAgents", null, function(resp) { + that.setState({ + cpu: Math.ceil(resp.stats.perc_cpu*100), + mem: Math.ceil(resp.stats.perc_mem*100) + }); + // latest.cpu = Math.ceil(resp.stats.perc_cpu*100);//100; + // latest.mem = Math.ceil(resp.stats.perc_mem*100);//100; + }); + PubSub.broadcast("ErizoAgent.getErizoJSInfo", null, function(resp) { + that.setState({erizos: resp.erizos}); + }); + + setTimeout(this.updateLicodeData, DATA_INTERVAL); + }, + + componentDidMount: function () { + var that = this; + this.updateLicodeData(); + + // PubSub.subscribe('stats', function(stat) { + // var stats = that.state.stats; + // stats[stat.pub] = stat; + // // console.log('got hhhheeeeee', resp); + // that.setState({stats: stats}); + // }); + }, + + render: function() { + return ( +
+

Licode Admin

+
+ + +
+
+ +
+
+ ); + } + }); +}); \ No newline at end of file diff --git a/admin/public/js/components/erizo_item.jsx b/admin/public/js/components/erizo_item.jsx new file mode 100644 index 0000000000..f27f3e4d11 --- /dev/null +++ b/admin/public/js/components/erizo_item.jsx @@ -0,0 +1,65 @@ +define(['react', 'pubsub'], function (React, PubSub) { + + return React.createClass({ + displayName: 'ErizoItem', + + getInitialState: function() { + return { + publisherMetadata: {} + }; + }, + + render: function() { + var that = this; + + return
  • +
    +
    {this.props.item.id}
    +
    {this.props.item.idle ? "idle" : "busy"}
    +
    {this.props.item.pid}
    +
      + { + Object.keys(that.state.publisherMetadata).map(function(p) { + var d = that.state.publisherMetadata[p]; + + return ( +
    • +
      {p}
      +
        +
      • {JSON.stringify(that.props.stats[p]) || "Statistics Disabled"}
      • + { + Object.keys(d).map(function(k) { + var v = d[k]; + return
      • {k} - {JSON.stringify(v)}
      • + }) + } +
      +
    • + ); + }) + } +
    +
    +
  • ; + + }, + + updatePublisherMetadata: function() { + var that = this; + + PubSub.call("ErizoJS_"+ this.props.item.id + ".getPublisherMetadata", null, function(resp) { + that.setState({publisherMetadata: resp}); + }); + }, + + componentDidMount: function() { + var that = this; + setInterval(function() { + that.updatePublisherMetadata(); + }, 2000); + }, + + }); + +}); + diff --git a/admin/public/js/components/erizo_list.jsx b/admin/public/js/components/erizo_list.jsx new file mode 100644 index 0000000000..6da0b5f0b5 --- /dev/null +++ b/admin/public/js/components/erizo_list.jsx @@ -0,0 +1,21 @@ +define(['react', 'jsx!components/erizo_item'], function (React, ErizoItem) { + + return React.createClass({ + displayName: 'ErizoList', + + getDefaultProps: function() { + return { erizos:[], stats: {} }; + }, + + render: function() { + var that = this; + var createItem = function(item) { + return ; + }; + + return ; + + } + }); +}); + diff --git a/admin/public/js/lib/react/.bower.json b/admin/public/js/lib/react/.bower.json new file mode 100644 index 0000000000..7048f28a82 --- /dev/null +++ b/admin/public/js/lib/react/.bower.json @@ -0,0 +1,19 @@ +{ + "name": "react", + "main": [ + "react.js", + "react-dom.js" + ], + "ignore": [], + "homepage": "https://github.com/facebook/react-bower", + "version": "0.14.6", + "_release": "0.14.6", + "_resolution": { + "type": "version", + "tag": "v0.14.6", + "commit": "b18cf6d3209c18da872e793d498e604e988d662d" + }, + "_source": "git://github.com/facebook/react-bower.git", + "_target": ">=0.11.2", + "_originalSource": "react" +} \ No newline at end of file diff --git a/admin/public/js/lib/react/LICENSE b/admin/public/js/lib/react/LICENSE new file mode 100644 index 0000000000..ce07c54d38 --- /dev/null +++ b/admin/public/js/lib/react/LICENSE @@ -0,0 +1,31 @@ +BSD License + +For react-bower software + +Copyright (c) 2013-2014, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/admin/public/js/lib/react/PATENTS b/admin/public/js/lib/react/PATENTS new file mode 100644 index 0000000000..20279b243a --- /dev/null +++ b/admin/public/js/lib/react/PATENTS @@ -0,0 +1,33 @@ +Additional Grant of Patent Rights Version 2 + +"Software" means the react-bower software distributed by Facebook, Inc. + +Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software +("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable +(subject to the termination provision below) license under any Necessary +Claims, to make, have made, use, sell, offer to sell, import, and otherwise +transfer the Software. For avoidance of doubt, no license is granted under +Facebook's rights in any patent claims that are infringed by (i) modifications +to the Software made by you or any third party or (ii) the Software in +combination with any software or other technology. + +The license granted hereunder will terminate, automatically and without notice, +if you (or any of your subsidiaries, corporate affiliates or agents) initiate +directly or indirectly, or take a direct financial interest in, any Patent +Assertion: (i) against Facebook or any of its subsidiaries or corporate +affiliates, (ii) against any party if such Patent Assertion arises in whole or +in part from any software, technology, product or service of Facebook or any of +its subsidiaries or corporate affiliates, or (iii) against any party relating +to the Software. Notwithstanding the foregoing, if Facebook or any of its +subsidiaries or corporate affiliates files a lawsuit alleging patent +infringement against you in the first instance, and you respond by filing a +patent infringement counterclaim in that lawsuit against that party that is +unrelated to the Software, the license granted hereunder will not terminate +under section (i) of this paragraph due to such counterclaim. + +A "Necessary Claim" is a claim of a patent owned by Facebook that is +necessarily infringed by the Software standing alone. + +A "Patent Assertion" is any lawsuit or other action alleging direct, indirect, +or contributory infringement or inducement to infringe any patent, including a +cross-claim or counterclaim. diff --git a/admin/public/js/lib/react/bower.json b/admin/public/js/lib/react/bower.json new file mode 100644 index 0000000000..4d0f00993d --- /dev/null +++ b/admin/public/js/lib/react/bower.json @@ -0,0 +1,5 @@ +{ + "name": "react", + "main": ["react.js", "react-dom.js"], + "ignore": [] +} diff --git a/admin/public/js/lib/react/react-dom-server.js b/admin/public/js/lib/react/react-dom-server.js new file mode 100644 index 0000000000..720f3fdd17 --- /dev/null +++ b/admin/public/js/lib/react/react-dom-server.js @@ -0,0 +1,42 @@ +/** + * ReactDOMServer v0.14.6 + * + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ +// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js +;(function(f) { + // CommonJS + if (typeof exports === "object" && typeof module !== "undefined") { + module.exports = f(require('react')); + + // RequireJS + } else if (typeof define === "function" && define.amd) { + define(['react'], f); + + // + + +
    + + + diff --git a/admin/client/src/admin.js b/admin/views/layout.ejs similarity index 100% rename from admin/client/src/admin.js rename to admin/views/layout.ejs diff --git a/admin/test.html b/admin/views/test.ejs similarity index 100% rename from admin/test.html rename to admin/views/test.ejs diff --git a/erizo_controller/erizoAgent/erizoAgent.js b/erizo_controller/erizoAgent/erizoAgent.js index d75c43e481..f2b39ec570 100644 --- a/erizo_controller/erizoAgent/erizoAgent.js +++ b/erizo_controller/erizoAgent/erizoAgent.js @@ -184,15 +184,11 @@ var reporter = require('./erizoAgentReporter').Reporter({id: my_erizo_agent_id, var api = { getErizoJSInfo: function(callback) { - p_trans = {} + p_trans = [] for (i in processes) { - p_trans[i] = {pid: processes[i].pid, killed: processes[i].killed, connected: processes[i].connected}; + p_trans.push({ id: i, pid: processes[i].pid, killed: processes[i].killed, connected: processes[i].connected, idle: (idle_erizos.indexOf(i) >= 0) }); } - callback({ - processes: p_trans, - erizos: erizos, - idle_erizos: idle_erizos - }); + callback({erizos: p_trans}); }, createErizoJS: function(callback) { try { diff --git a/erizo_controller/erizoClient/src/Stream.js b/erizo_controller/erizoClient/src/Stream.js index c877f6eabc..ba338b03ff 100644 --- a/erizo_controller/erizoClient/src/Stream.js +++ b/erizo_controller/erizoClient/src/Stream.js @@ -85,7 +85,7 @@ Erizo.Stream = function (spec) { } else if (spec.screen == true && videoOpt === undefined){ videoOpt = true; } - var opt = {video: videoOpt, audio: spec.audio, fake: spec.fake, screen: spec.screen, extensionId:that.extensionId}; + var opt = {video: videoOpt, audio: spec.audio, fake: spec.fake, screen: spec.screen, extensionId:that.extensionId, attributes: spec.attributes}; L.Logger.debug(opt); Erizo.GetUserMedia(opt, function (stream) { //navigator.webkitGetUserMedia("audio, video", function (stream) { diff --git a/erizo_controller/erizoController/roomController.js b/erizo_controller/erizoController/roomController.js index 8fa7b74751..1d775511dc 100644 --- a/erizo_controller/erizoController/roomController.js +++ b/erizo_controller/erizoController/roomController.js @@ -190,9 +190,9 @@ exports.RoomController = function (spec) { //TODO: Possible race condition if we got an old id amqper.callRpc(getErizoQueue(publisher_id), "addPublisher", args, {callback: callback}); - // amqper.callRpc(getErizoQueue(publisher_id), "addPublisherMetadata", [options], {callback: function() { - // log.info("Passed publisher metadata over to erizoJS ", publisher_id); - // }}); + amqper.callRpc(getErizoQueue(publisher_id), "addPublisherMetadata", [publisher_id, options], {callback: function() { + log.info("Passed publisher metadata over to erizoJS ", publisher_id, options); + }}); erizos[erizo_id].publishers.push(publisher_id); }); diff --git a/erizo_controller/erizoJS/erizoJSController.js b/erizo_controller/erizoJS/erizoJSController.js index 048af5548c..d9a381a94d 100644 --- a/erizo_controller/erizoJS/erizoJSController.js +++ b/erizo_controller/erizoJS/erizoJSController.js @@ -176,6 +176,7 @@ exports.ErizoJSController = function (spec) { if (GLOBAL.config.erizoController.report.rtcp_stats) { wrtc.getStats(function (newStats){ var timeStamp = new Date(); + console.log("broadcasting stats:", id_pub, theStats); amqper.broadcast('stats', {pub: id_pub, subs: id_sub, stats: theStats, timestamp:timeStamp.getTime()}); }); } @@ -389,13 +390,13 @@ exports.ErizoJSController = function (spec) { }; - that.addPublisherMetadata = function(data, callback) { - metadata = data; - callback(true); + that.addPublisherMetadata = function(from, data, callback) { + metadata[from] = data; + callback('callback', true); }; that.getPublisherMetadata = function(callback) { - callback(metadata); + callback('callback', metadata); }; /* diff --git a/extras/basic_example/public/script.js b/extras/basic_example/public/script.js index 838d4dd3e3..3cca5f56f0 100644 --- a/extras/basic_example/public/script.js +++ b/extras/basic_example/public/script.js @@ -30,7 +30,7 @@ function startRecording () { window.onload = function () { recording = false; var screen = getParameterByName("screen"); - var config = {audio: true, video: true, data: true, screen: screen, videoSize: [640, 480, 640, 480]}; + var config = {audio: true, video: true, data: true, screen: screen, videoSize: [640, 480, 640, 480], attributes: {user: "gene", class: 1234}}; // If we want screen sharing we have to put our Chrome extension id. The default one only works in our Lynckia test servers. // If we are not using chrome, the creation of the stream will fail regardless. if (screen){ diff --git a/scripts/installUbuntuDepsUnattended.sh b/scripts/installUbuntuDepsUnattended.sh index 9883df6117..ca70fa01f9 100755 --- a/scripts/installUbuntuDepsUnattended.sh +++ b/scripts/installUbuntuDepsUnattended.sh @@ -58,7 +58,7 @@ install_openssl(){ if [ -d $LIB_DIR ]; then cd $LIB_DIR if [ ! -f ./openssl-1.0.1g.tar.gz ]; then - curl -O http://www.openssl.org/source/openssl-1.0.1g.tar.gz + curl -O ftp://ftp.openssl.org/source/old/1.0.1/openssl-1.0.1g.tar.gz tar -zxvf openssl-1.0.1g.tar.gz cd openssl-1.0.1g ./config --prefix=$PREFIX_DIR -fPIC From 3396c063387850333f7f485046d763c5a1d43eb1 Mon Sep 17 00:00:00 2001 From: Gene Hallman Date: Sun, 24 Jan 2016 16:41:53 -0800 Subject: [PATCH 2/4] working switch now --- admin/public/js/components/dashboard.jsx | 21 +++++++++++---------- admin/public/js/components/erizo_item.jsx | 11 +++++++++-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/admin/public/js/components/dashboard.jsx b/admin/public/js/components/dashboard.jsx index 9fbc5ea2ae..a74bd7992e 100644 --- a/admin/public/js/components/dashboard.jsx +++ b/admin/public/js/components/dashboard.jsx @@ -7,7 +7,7 @@ define(['pubsub', 'jsx!components/charts', 'react', 'jsx!components/erizo_list'] displayName: 'Dashboard', getInitialState: function() { - return { cpu:0, mem:0, erizos:[], stats: {} } + return { cpu:0, mem:0, erizos:[], stats: {}, showStats: false } }, updateLicodeData: function() { @@ -18,8 +18,6 @@ define(['pubsub', 'jsx!components/charts', 'react', 'jsx!components/erizo_list'] cpu: Math.ceil(resp.stats.perc_cpu*100), mem: Math.ceil(resp.stats.perc_mem*100) }); - // latest.cpu = Math.ceil(resp.stats.perc_cpu*100);//100; - // latest.mem = Math.ceil(resp.stats.perc_mem*100);//100; }); PubSub.broadcast("ErizoAgent.getErizoJSInfo", null, function(resp) { that.setState({erizos: resp.erizos}); @@ -32,15 +30,16 @@ define(['pubsub', 'jsx!components/charts', 'react', 'jsx!components/erizo_list'] var that = this; this.updateLicodeData(); - // PubSub.subscribe('stats', function(stat) { - // var stats = that.state.stats; - // stats[stat.pub] = stat; - // // console.log('got hhhheeeeee', resp); - // that.setState({stats: stats}); - // }); + PubSub.subscribe('stats', function(stat) { + var stats = that.state.stats; + stats[stat.pub] = stat; + that.setState({stats: stats}); + }); }, + render: function() { + var that = this; return (

    Licode Admin

    @@ -48,8 +47,10 @@ define(['pubsub', 'jsx!components/charts', 'react', 'jsx!components/erizo_list']
    + +
    - +
    ); diff --git a/admin/public/js/components/erizo_item.jsx b/admin/public/js/components/erizo_item.jsx index f27f3e4d11..f2175070b7 100644 --- a/admin/public/js/components/erizo_item.jsx +++ b/admin/public/js/components/erizo_item.jsx @@ -48,16 +48,23 @@ define(['react', 'pubsub'], function (React, PubSub) { var that = this; PubSub.call("ErizoJS_"+ this.props.item.id + ".getPublisherMetadata", null, function(resp) { - that.setState({publisherMetadata: resp}); + if (that.isMounted()) { + that.setState({publisherMetadata: resp}); + } }); }, componentDidMount: function() { var that = this; - setInterval(function() { + this.interval = setInterval(function() { that.updatePublisherMetadata(); }, 2000); }, + componentWillUnmount: function() { + if (this.interval) { + clearInterval(this.interval); + } + } }); From e61a8dcc985675c8093ab11bd2557d6c70bae106 Mon Sep 17 00:00:00 2001 From: Gene Hallman Date: Sun, 24 Jan 2016 20:57:21 -0800 Subject: [PATCH 3/4] made the admin look awesome --- admin/public/css/style.css | 109 ++++++++++++++++-- admin/public/js/components/charts.jsx | 55 +++++---- admin/public/js/components/dashboard.jsx | 53 +-------- admin/public/js/components/erizo_item.jsx | 51 ++++---- admin/public/js/components/erizo_list.jsx | 52 ++++++++- .../public/js/components/erizo_publisher.jsx | 62 ++++++++++ admin/public/js/components/host_stats.jsx | 41 +++++++ 7 files changed, 307 insertions(+), 116 deletions(-) create mode 100644 admin/public/js/components/erizo_publisher.jsx create mode 100644 admin/public/js/components/host_stats.jsx diff --git a/admin/public/css/style.css b/admin/public/css/style.css index 3087d05523..2307f3c3f9 100644 --- a/admin/public/css/style.css +++ b/admin/public/css/style.css @@ -1,28 +1,117 @@ +.page-header { + padding-left:20px; + padding-right:20px; + margin-top:0px; + padding-top:30px; + border-bottom-color:#ddd; + background-color:#eee; + +} .x.axis line { shape-rendering: auto; } -.line { - fill: none; - stroke: #000; - stroke-width: 1.5px; +.host_stats { + padding:20px; + float:right; + background-color:; +} + +.host_stats h4 { + text-align: center } -table { + +.erizo_list { + margin-right:600px; + padding:20px; + +} + +.graph { margin-top:10px; margin-bottom:10px; } -td { + +.graph td { padding:0px; padding-top:10px; margin-top:10px; - width: 60px; text-align:center; } -td.header { + +.graph td.header { width: 90px; text-align:left; -} + vertical-align: middle; + text-align: center; + font-size:15px; + text-transform: uppercase; +} +.graph td.values div { + margin-bottom:15px; + font-size:12px; + text-transform: uppercase; +} -#graphHolder svg { +.graph svg { overflow: visible; } + +.graph svg .y_axis text { + font-size:10px; +} + +.graph svg .y_axis .domain { + fill: none; + stroke: #337ab7; + stroke-width: 1px; +} + +.graph svg .line { + fill: none; + stroke: #337ab7; + stroke-width: 2px; +} + +.erizo_item .panel-heading > div { + display:inline-block; + font-size:16px; + margin-right:30px; +} + +.erizo_list .panel-body::before, +.erizo_list .panel-body::after { + display:inline; +} + +.erizo_publisher .panel-heading > span { + display:inline-block; + font-size:13px; + margin:9px; + margin-right:15px; +} +.erizo_publisher .panel-heading > span.pub_id { + font-weight: bold; + font-size:14px; +} +.erizo_publisher .panel-heading > span.publisher_attrs { + font-family: monospace; + margin:0; + float:right; +} + +.erizo_publisher .stats_header { + font-family: monospace; + font-size:12px; + font-weight: bold; + margin:0; +} + +.erizo_publisher .stats_holder { + float:left; + text-align: center; + margin:20px 40px; +} + + + diff --git a/admin/public/js/components/charts.jsx b/admin/public/js/components/charts.jsx index a5e9ad4772..84ef7c34b8 100644 --- a/admin/public/js/components/charts.jsx +++ b/admin/public/js/components/charts.jsx @@ -1,18 +1,13 @@ define(['d3', 'react'], function(d3, React) { - var margin = {top: 5, right: 0, bottom: 5, left: 100}, - width = 450 - margin.right, - height = 90 - margin.top - margin.bottom; - - return React.createClass({ displayName: 'MovingLineChart', getInitialState: function() { var that = this; - this.x = d3.scale.linear().domain(this.props.xdomain).range([0, width]); - this.y = d3.scale.linear().domain(this.props.ydomain).range([height, 0]); + this.x = d3.scale.linear().domain(this.props.xdomain).range([0, this.props.width]); + this.y = d3.scale.linear().domain(this.props.ydomain).range([this.props.height, 0]); this.line = d3.svg.line() .interpolate(this.props.interpolation) .x(function(d, i) { return that.x(i); }) @@ -34,7 +29,10 @@ define(['d3', 'react'], function(d3, React) { title: "Chart", ydomain: [0, 100], xdomain: [1, 300], - interpolation: "basis", + interpolation: "basis", + width: 450, + y_width: 50, + height: 90, value: 0 } }, @@ -42,21 +40,32 @@ define(['d3', 'react'], function(d3, React) { render: function() { return ( - - - - - - -
    {this.props.title} - - - - - - - - {this.props.value}{this.state.minVal}{this.state.maxVal}
    + + + + + + + + + + + +
    + {this.props.title} +
    + + + + + + + + +
    Current{this.props.value}
    +
    Min{this.state.minVal}
    +
    Max{this.state.maxVal}
    +
    ); }, diff --git a/admin/public/js/components/dashboard.jsx b/admin/public/js/components/dashboard.jsx index a74bd7992e..ac2e465287 100644 --- a/admin/public/js/components/dashboard.jsx +++ b/admin/public/js/components/dashboard.jsx @@ -1,57 +1,16 @@ -define(['pubsub', 'jsx!components/charts', 'react', 'jsx!components/erizo_list'], function (PubSub, MovingLineChart, React, ErizoList) { - var xdomain_length = 300; - var DATA_INTERVAL = 5000; - var latest = {cpu:0, mem:0}; +define(['react', 'jsx!components/host_stats', 'jsx!components/erizo_list'], function (React, HostStats, ErizoList) { return React.createClass({ displayName: 'Dashboard', - getInitialState: function() { - return { cpu:0, mem:0, erizos:[], stats: {}, showStats: false } - }, - - updateLicodeData: function() { - var that = this; - - PubSub.broadcast("ErizoAgent.getErizoAgents", null, function(resp) { - that.setState({ - cpu: Math.ceil(resp.stats.perc_cpu*100), - mem: Math.ceil(resp.stats.perc_mem*100) - }); - }); - PubSub.broadcast("ErizoAgent.getErizoJSInfo", null, function(resp) { - that.setState({erizos: resp.erizos}); - }); - - setTimeout(this.updateLicodeData, DATA_INTERVAL); - }, - - componentDidMount: function () { - var that = this; - this.updateLicodeData(); - - PubSub.subscribe('stats', function(stat) { - var stats = that.state.stats; - stats[stat.pub] = stat; - that.setState({stats: stats}); - }); - }, - - render: function() { - var that = this; return (
    -

    Licode Admin

    -
    - - -
    - - -
    - -
    +

    Licode Admin

    + + + +
    ); } diff --git a/admin/public/js/components/erizo_item.jsx b/admin/public/js/components/erizo_item.jsx index f2175070b7..3120190f0a 100644 --- a/admin/public/js/components/erizo_item.jsx +++ b/admin/public/js/components/erizo_item.jsx @@ -1,47 +1,37 @@ -define(['react', 'pubsub'], function (React, PubSub) { +define(['pubsub', 'react', 'jsx!components/erizo_publisher'], function (PubSub, React, ErizoPublisher) { return React.createClass({ displayName: 'ErizoItem', getInitialState: function() { return { - publisherMetadata: {} + publisherMetadata: {} }; }, render: function() { var that = this; - return
  • -
    -
    {this.props.item.id}
    -
    {this.props.item.idle ? "idle" : "busy"}
    -
    {this.props.item.pid}
    -
      - { - Object.keys(that.state.publisherMetadata).map(function(p) { - var d = that.state.publisherMetadata[p]; + var createItem = function(key) { + return ( + + ); + }; - return ( -
    • -
      {p}
      -
        -
      • {JSON.stringify(that.props.stats[p]) || "Statistics Disabled"}
      • - { - Object.keys(d).map(function(k) { - var v = d[k]; - return
      • {k} - {JSON.stringify(v)}
      • - }) - } -
      -
    • - ); - }) - } -
    + return ( +
    +
    +
    ErizoJS_{this.props.item.id}
    +
    PID{this.props.item.pid}
    +
    State{this.props.item.idle ? "idle" : "busy"}
    +
    + { (Object.keys(that.state.publisherMetadata).length == 0 ? "" : ( +
    + { Object.keys(that.state.publisherMetadata).map(createItem) } +
    + )) }
    -
  • ; - + ); }, updatePublisherMetadata: function() { @@ -60,6 +50,7 @@ define(['react', 'pubsub'], function (React, PubSub) { that.updatePublisherMetadata(); }, 2000); }, + componentWillUnmount: function() { if (this.interval) { clearInterval(this.interval); diff --git a/admin/public/js/components/erizo_list.jsx b/admin/public/js/components/erizo_list.jsx index 6da0b5f0b5..f47f5873ed 100644 --- a/admin/public/js/components/erizo_list.jsx +++ b/admin/public/js/components/erizo_list.jsx @@ -1,20 +1,60 @@ -define(['react', 'jsx!components/erizo_item'], function (React, ErizoItem) { +define(['pubsub', 'react', 'jsx!components/erizo_item'], function (PubSub, React, ErizoItem) { + + var DATA_INTERVAL = 5000; return React.createClass({ displayName: 'ErizoList', + getInitialState: function() { + return { erizos:[], stats: {}, showStats: false } + }, + getDefaultProps: function() { - return { erizos:[], stats: {} }; + return { stats: {} }; + }, + + updateErizoJSData: function() { + var that = this; + + PubSub.broadcast("ErizoAgent.getErizoJSInfo", null, function(resp) { + that.setState({erizos: resp.erizos}); + }); + + setTimeout(this.updateErizoJSData, DATA_INTERVAL); + }, + + componentDidMount: function () { + var that = this; + this.updateErizoJSData(); + + PubSub.subscribe('stats', function(stat) { + var stats = that.state.stats; + stats[stat.pub] = stat; + that.setState({stats: stats}); + }); }, render: function() { var that = this; var createItem = function(item) { - return ; + return ( + + ); }; - - return
      { this.props.erizos.map(createItem) }
    ; - + return ( +
    +
    +

    Erizo JS Processes

    +
    + +
    +
    { this.state.erizos.map(createItem) }
    +
    +
    + ); } }); }); diff --git a/admin/public/js/components/erizo_publisher.jsx b/admin/public/js/components/erizo_publisher.jsx new file mode 100644 index 0000000000..1d72600a1e --- /dev/null +++ b/admin/public/js/components/erizo_publisher.jsx @@ -0,0 +1,62 @@ +define(['react', 'jsx!components/charts'], function (React, MovingLineChart) { + var stat_keys = ["fractionLost", "jitter", "packetsLost", "rtcpBytesSent", "rtcpPacketSent"]; + var ydomains = { + "fractionLost": [0, 1000], + "jitter": [0, 10000000000], + "packetsLost": [0, 100000000], + "rtcpBytesSent": [0, 10000000], + "rtcpPacketSent": [0, 100000] + } + return React.createClass({ + displayName: 'ErizoPublisher', + + render: function() { + var that = this; + + var showStats = function(k) { + if (!that.props.stats) { + return null; + } + console.log('got here') + + return ( +
    + { that.props.stats.stats.map(function(stats) { + return ( +
    + {JSON.stringify({type:stats.type, ssrc:stats.ssrc, sourcSsrc:(stats.sourcSsrc || "")})} + { stat_keys.map(function(k) { + return (!(k in stats) ? null : ()); + }) } + +
    + ); + + }) } +
    + +
    + ); + + }; + + return ( +
    +
    + Publisher: {this.props.pub} + Data + Audio + Video + Screen + {JSON.stringify(this.props.item.attributes)} +
    + { showStats() } +
    + ); + + }, + + }); + +}); + diff --git a/admin/public/js/components/host_stats.jsx b/admin/public/js/components/host_stats.jsx new file mode 100644 index 0000000000..d012f0d4fc --- /dev/null +++ b/admin/public/js/components/host_stats.jsx @@ -0,0 +1,41 @@ +define(['pubsub', 'react', 'jsx!components/charts'], function (PubSub, React, MovingLineChart) { + + var xdomain_length = 300; + var DATA_INTERVAL = 5000; + + return React.createClass({ + displayName: 'HostStats', + + getInitialState: function() { + return { cpu: 0, mem: 0 }; + }, + + updateHostData: function() { + var that = this; + + PubSub.broadcast("ErizoAgent.getErizoAgents", null, function(resp) { + that.setState({ + cpu: Math.ceil(resp.stats.perc_cpu*100), + mem: Math.ceil(resp.stats.perc_mem*100) + }); + }); + + setTimeout(this.updateHostData, DATA_INTERVAL); + }, + + componentDidMount: function () { + this.updateHostData(); + }, + + render: function() { + return ( +
    +

    Host Stats

    + + +
    + ); + } + }); +}); + From 5e46c205994b934031f9a1419ad89f720e166ed7 Mon Sep 17 00:00:00 2001 From: Gene Hallman Date: Mon, 25 Jan 2016 09:53:47 -0800 Subject: [PATCH 4/4] made it prettier and work better --- admin/public/css/style.css | 3 ++- admin/public/js/components/charts.jsx | 7 ++++--- admin/public/js/components/erizo_publisher.jsx | 1 - admin/public/js/components/host_stats.jsx | 10 +++++++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/admin/public/css/style.css b/admin/public/css/style.css index 2307f3c3f9..da393d5706 100644 --- a/admin/public/css/style.css +++ b/admin/public/css/style.css @@ -2,6 +2,7 @@ padding-left:20px; padding-right:20px; margin-top:0px; + margin-bottom:0px; padding-top:30px; border-bottom-color:#ddd; background-color:#eee; @@ -22,7 +23,7 @@ } .erizo_list { - margin-right:600px; + margin-right:540px; padding:20px; } diff --git a/admin/public/js/components/charts.jsx b/admin/public/js/components/charts.jsx index 84ef7c34b8..00c8f75fa4 100644 --- a/admin/public/js/components/charts.jsx +++ b/admin/public/js/components/charts.jsx @@ -30,10 +30,11 @@ define(['d3', 'react'], function(d3, React) { ydomain: [0, 100], xdomain: [1, 300], interpolation: "basis", - width: 450, + width: 400, y_width: 50, height: 90, - value: 0 + value: 0, + animationRate: 40 } }, @@ -91,7 +92,7 @@ define(['d3', 'react'], function(d3, React) { // redraw the line, and then slide it to the left d3.select(that.refs.path) .transition() - .duration(100) + .duration(that.props.animationRate) .ease("linear") .attr("transform", "translate(" + that.x(0) + ")") .each("end", function() { that.updateGraphData(); }); diff --git a/admin/public/js/components/erizo_publisher.jsx b/admin/public/js/components/erizo_publisher.jsx index 1d72600a1e..3108738f4c 100644 --- a/admin/public/js/components/erizo_publisher.jsx +++ b/admin/public/js/components/erizo_publisher.jsx @@ -17,7 +17,6 @@ define(['react', 'jsx!components/charts'], function (React, MovingLineChart) { if (!that.props.stats) { return null; } - console.log('got here') return (
    diff --git a/admin/public/js/components/host_stats.jsx b/admin/public/js/components/host_stats.jsx index d012f0d4fc..5fc42402da 100644 --- a/admin/public/js/components/host_stats.jsx +++ b/admin/public/js/components/host_stats.jsx @@ -30,9 +30,13 @@ define(['pubsub', 'react', 'jsx!components/charts'], function (PubSub, React, Mo render: function() { return (
    -

    Host Stats

    - - +
    +

    Host Stats

    +
    + + +
    +
    ); }