From b1c24b444cba6db8c505497ba6a41a48a3ebb101 Mon Sep 17 00:00:00 2001 From: Pete Richards Date: Fri, 21 Jul 2017 16:47:05 -0700 Subject: [PATCH] time system is required for telemetry Simplify realtime provider Due to https://github.com/nasa/openmct/issues/1594 we no longer need to worry about multiple calls for the same identifier. Host all routes on same port, use host-relative urls for client Update readme --- README.md | 39 +++++++---------- example-server/history-server.js | 18 +++----- example-server/realtime-server.js | 70 +++++++++++++++---------------- example-server/server.js | 20 +++++++-- example-server/static-server.js | 16 ++++--- historical-telemetry-plugin.js | 2 +- index.html | 1 + package.json | 5 ++- realtime-telemetry-plugin.js | 33 +++++---------- 9 files changed, 93 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 95dc412..d78225a 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ We're going to define a single `index.html` page. We'll include the Open MCT li openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.UTCTimeSystem()); openmct.time.clock('local', {start: -15 * 60 * 1000, end: 0}); + openmct.time.timeSystem('utc'); openmct.install(openmct.plugins.Espresso()); openmct.start(); @@ -128,6 +129,7 @@ Next, we'll update index.html to include the file: openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.UTCTimeSystem()); openmct.time.clock('local', {start: -15 * 60 * 1000, end: 0}); + openmct.time.timeSystem('utc'); openmct.install(openmct.plugins.Espresso()); openmct.install(DictionaryPlugin()); @@ -416,7 +418,7 @@ function HistoricalTelemetryPlugin() { return domainObject.type === 'example.telemetry'; }, request: function (domainObject, options) { - var url = 'http://localhost:8081/telemetry/' + + var url = '/history/' + domainObject.identifier.key + '?start=' + options.start + '&end=' + options.end; @@ -457,6 +459,7 @@ With our adapter defined, we need to update `index.html` to include it. openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.UTCTimeSystem()); openmct.time.clock('local', {start: -15 * 60 * 1000, end: 0}); + openmct.time.timeSystem('utc'); openmct.install(openmct.plugins.Espresso()); openmct.install(DictionaryPlugin()); @@ -484,15 +487,13 @@ Let's define our new plugin in a file named `realtime-telemetry-plugin.js`. */ function RealtimeTelemetryPlugin() { return function (openmct) { - var socket = new WebSocket('ws://localhost:8082'); - var listeners = {}; + var socket = new WebSocket(location.origin.replace(/^http/, 'ws') + '/realtime/'); + var listener = {}; socket.onmessage = function (event) { point = JSON.parse(event.data); - if (listeners[point.id]) { - listeners[point.id].forEach(function (l) { - l(point); - }); + if (listener[point.id]) { + listener[point.id](point); } }; @@ -500,23 +501,12 @@ function RealtimeTelemetryPlugin() { supportsSubscribe: function (domainObject) { return domainObject.type === 'example.telemetry'; }, - subscribe: function (domainObject, callback, options) { - if (!listeners[domainObject.identifier.key]) { - listeners[domainObject.identifier.key] = []; - } - if (!listeners[domainObject.identifier.key].length) { - socket.send('subscribe ' + domainObject.identifier.key); - } - listeners[domainObject.identifier.key].push(callback); - return function () { - listeners[domainObject.identifier.key] = - listeners[domainObject.identifier.key].filter(function (c) { - return c !== callback; - }); - - if (!listeners[domainObject.identifier.key].length) { - socket.send('unsubscribe ' + domainObject.identifier.key); - } + subscribe: function (domainObject, callback) { + listener[domainObject.identifier.key] = callback; + socket.send('subscribe ' + domainObject.identifier.key); + return function unsubscribe() { + delete listener[domainObject.identifier.key]; + socket.send('unsubscribe ' + domainObject.identifier.key); }; } }; @@ -549,6 +539,7 @@ With our realtime telemetry plugin defined, let's include it from `index.html`. openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.UTCTimeSystem()); openmct.time.clock('local', {start: -15 * 60 * 1000, end: 0}); + openmct.time.timeSystem('utc'); openmct.install(openmct.plugins.Espresso()); openmct.install(DictionaryPlugin()); diff --git a/example-server/history-server.js b/example-server/history-server.js index 9753d29..ab3eaaa 100644 --- a/example-server/history-server.js +++ b/example-server/history-server.js @@ -1,20 +1,13 @@ - - var express = require('express'); -function HistoryServer(spacecraft, port) { - server = express(); +function HistoryServer(spacecraft) { + var router = express.Router(); - server.use(function (req, res, next) { - res.set('Access-Control-Allow-Origin', '*'); - next(); - }); - - server.get('/telemetry/:pointId', function (req, res) { + router.get('/:pointId', function (req, res) { var start = +req.query.start; var end = +req.query.end; var ids = req.params.pointId.split(','); - + var response = ids.reduce(function (resp, id) { return resp.concat(spacecraft.history[id].filter(function (p) { return p.timestamp > start && p.timestamp < end; @@ -23,8 +16,7 @@ function HistoryServer(spacecraft, port) { res.status(200).json(response).end(); }); - server.listen(port); - console.log('History server now running at http://localhost:' + port); + return router; } module.exports = HistoryServer; diff --git a/example-server/realtime-server.js b/example-server/realtime-server.js index 5362fae..fce443b 100644 --- a/example-server/realtime-server.js +++ b/example-server/realtime-server.js @@ -1,43 +1,41 @@ -var WebSocketServer = require('ws').Server; - -function RealtimeServer(spacecraft, port) { - this.spacecraft = spacecraft; - this.server = new WebSocketServer({ port: port }); - this.server.on('connection', this.handleConnection.bind(this)); - console.log('Realtime server started at ws://localhost:' + port); -}; +var express = require('express'); + +function RealtimeServer(spacecraft) { + + var router = express.Router(); + + router.ws('/', function (ws) { + var unlisten = spacecraft.listen(notifySubscribers); + var subscribed = {}; // Active subscriptions for this connection + var handlers = { // Handlers for specific requests + subscribe: function (id) { + subscribed[id] = true; + }, + unsubscribe: function (id) { + delete subscribed[id]; + } + }; + + function notifySubscribers(point) { + if (subscribed[point.id]) { + ws.send(JSON.stringify(point)); + } + } -RealtimeServer.prototype.handleConnection = function (ws) { - var unlisten = this.spacecraft.listen(notifySubscribers); - subscribed = {}, // Active subscriptions for this connection - handlers = { // Handlers for specific requests - subscribe: function (id) { - subscribed[id] = true; - }, - unsubscribe: function (id) { - delete subscribed[id]; + // Listen for requests + ws.on('message', function (message) { + var parts = message.split(' '), + handler = handlers[parts[0]]; + if (handler) { + handler.apply(handlers, parts.slice(1)); } - }; + }); - function notifySubscribers(point) { - if (subscribed[point.id]) { - ws.send(JSON.stringify(point)); - } - } - - // Listen for requests - ws.on('message', function (message) { - var parts = message.split(' '), - handler = handlers[parts[0]]; - if (handler) { - handler.apply(handlers, parts.slice(1)); - } + // Stop sending telemetry updates for this connection when closed + ws.on('close', unlisten); }); - // Stop sending telemetry updates for this connection when closed - ws.on('close', unlisten); + return router; }; - - -module.exports = RealtimeServer; \ No newline at end of file +module.exports = RealtimeServer; diff --git a/example-server/server.js b/example-server/server.js index 5fc9968..ff873c1 100644 --- a/example-server/server.js +++ b/example-server/server.js @@ -7,9 +7,23 @@ var RealtimeServer = require('./realtime-server'); var HistoryServer = require('./history-server'); var StaticServer = require('./static-server'); +var expressWs = require('express-ws'); +var app = require('express')(); +expressWs(app); var spacecraft = new Spacecraft(); -var realtimeServer = new RealtimeServer(spacecraft, 8082); -var historyServer = new HistoryServer(spacecraft, 8081); -var staticServer = new StaticServer(8080); +var realtimeServer = new RealtimeServer(spacecraft); +var historyServer = new HistoryServer(spacecraft); +var staticServer = new StaticServer(); +app.use('/realtime', realtimeServer); +app.use('/history', historyServer); +app.use('/', staticServer); + +var port = process.env.PORT || 8080 + +app.listen(port, function () { + console.log('Open MCT hosted at http://localhost:' + port); + console.log('History hosted at http://localhost:' + port + '/history'); + console.log('Realtime hosted at ws://localhost:' + port + '/realtime'); +}); diff --git a/example-server/static-server.js b/example-server/static-server.js index 385e2ff..e0ccd93 100644 --- a/example-server/static-server.js +++ b/example-server/static-server.js @@ -1,13 +1,11 @@ var express = require('express'); -function StaticServer(port) { - var server = express(); - - server.use('/', express.static(__dirname + '/..')); - - console.log('Open MCT hosted at http://localhost:' + port); - - server.listen(port); +function StaticServer() { + var router = express.Router(); + + router.use('/', express.static(__dirname + '/..')); + + return router } -module.exports = StaticServer; \ No newline at end of file +module.exports = StaticServer; diff --git a/historical-telemetry-plugin.js b/historical-telemetry-plugin.js index f7f7267..3c44905 100644 --- a/historical-telemetry-plugin.js +++ b/historical-telemetry-plugin.js @@ -9,7 +9,7 @@ function HistoricalTelemetryPlugin() { return domainObject.type === 'example.telemetry'; }, request: function (domainObject, options) { - var url = 'http://localhost:8081/telemetry/' + + var url = '/history/' + domainObject.identifier.key + '?start=' + options.start + '&end=' + options.end; diff --git a/index.html b/index.html index b8e4bb4..8b9cdf3 100644 --- a/index.html +++ b/index.html @@ -15,6 +15,7 @@ openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.UTCTimeSystem()); openmct.time.clock('local', {start: -15 * 60 * 1000, end: 0}); + openmct.time.timeSystem('utc'); openmct.install(openmct.plugins.Espresso()); openmct.install(DictionaryPlugin()); diff --git a/package.json b/package.json index 8367228..d2813e8 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "homepage": "https://github.com/nasa/openmct-tutorial#readme", "dependencies": { "express": "^4.14.1", - "ws": "^2.0.3", - "openmct": "nasa/openmct" + "express-ws": "^3.0.0", + "openmct": "nasa/openmct", + "ws": "^2.0.3" } } diff --git a/realtime-telemetry-plugin.js b/realtime-telemetry-plugin.js index 0b35bdd..b4d32ae 100644 --- a/realtime-telemetry-plugin.js +++ b/realtime-telemetry-plugin.js @@ -3,15 +3,13 @@ */ function RealtimeTelemetryPlugin() { return function (openmct) { - var socket = new WebSocket('ws://localhost:8082'); - var listeners = {}; + var socket = new WebSocket(location.origin.replace(/^http/, 'ws') + '/realtime/'); + var listener = {}; socket.onmessage = function (event) { point = JSON.parse(event.data); - if (listeners[point.id]) { - listeners[point.id].forEach(function (l) { - l(point); - }); + if (listener[point.id]) { + listener[point.id](point); } }; @@ -19,23 +17,12 @@ function RealtimeTelemetryPlugin() { supportsSubscribe: function (domainObject) { return domainObject.type === 'example.telemetry'; }, - subscribe: function (domainObject, callback, options) { - if (!listeners[domainObject.identifier.key]) { - listeners[domainObject.identifier.key] = []; - } - if (!listeners[domainObject.identifier.key].length) { - socket.send('subscribe ' + domainObject.identifier.key); - } - listeners[domainObject.identifier.key].push(callback); - return function () { - listeners[domainObject.identifier.key] = - listeners[domainObject.identifier.key].filter(function (c) { - return c !== callback; - }); - - if (!listeners[domainObject.identifier.key].length) { - socket.send('unsubscribe ' + domainObject.identifier.key); - } + subscribe: function (domainObject, callback) { + listener[domainObject.identifier.key] = callback; + socket.send('subscribe ' + domainObject.identifier.key); + return function unsubscribe() { + delete listener[domainObject.identifier.key]; + socket.send('unsubscribe ' + domainObject.identifier.key); }; } };