Deprecating old web-socket stuff and adding ability for client-side message handler registration. Failover still to be done and same for the async hooks.
Change-Id: I6029c91eb1a04e01401e495b9673ddaea728e215
diff --git a/web/gui/src/main/webapp/app/fw/remote/websocket.js b/web/gui/src/main/webapp/app/fw/remote/websocket.js
index abe6025..3229250 100644
--- a/web/gui/src/main/webapp/app/fw/remote/websocket.js
+++ b/web/gui/src/main/webapp/app/fw/remote/websocket.js
@@ -20,62 +20,105 @@
(function () {
'use strict';
- var fs;
+ // injected refs
+ var fs, $log;
- function fnOpen(f) {
- // wrap the onOpen function; we will handle any housekeeping here...
- if (!fs.isF(f)) {
- return null;
- }
+ // internal state
+ var ws, sws, sid = 0,
+ handlers = {};
- return function (openEvent) {
- // NOTE: nothing worth passing to the caller?
- f();
- };
+ function resetSid() {
+ sid = 0;
}
- function fnMessage(f) {
- // wrap the onMessage function; we will attempt to decode the
- // message event payload as JSON and pass that in...
- if (!fs.isF(f)) {
- return null;
- }
+ // Binds the specified message handlers.
+ function bindHandlers(handlerMap) {
+ var m = d3.map(handlerMap),
+ dups = [];
- return function (msgEvent) {
- var ev;
- try {
- ev = JSON.parse(msgEvent.data);
- } catch (e) {
- ev = {
- error: 'Failed to parse JSON',
- e: e
- };
+ m.forEach(function (key, value) {
+ var fn = fs.isF(value[key]);
+ if (!fn) {
+ $log.warn(key + ' binding not a function on ' + value);
+ return;
}
- f(ev);
- };
+
+ if (handlers[key]) {
+ dups.push(key);
+ } else {
+ handlers[key] = fn;
+ }
+ });
+ if (dups.length) {
+ $log.warn('duplicate bindings ignored:', dups);
+ }
}
- function fnClose(f) {
- // wrap the onClose function; we will handle any parameters to the
- // close event here...
- if (!fs.isF(f)) {
- return null;
- }
+ // Unbinds the specified message handlers.
+ function unbindHandlers(handlerMap) {
+ var m = d3.map(handlerMap);
+ m.forEach(function (key) {
+ delete handlers[key];
+ });
+ }
- return function (closeEvent) {
- // NOTE: only seen {reason == ""} so far, nevertheless...
- f(closeEvent.reason);
- };
+ // Formulates an event message and sends it via the shared web-socket.
+ function sendEvent(evType, payload) {
+ var p = payload || {};
+ if (sws) {
+ $log.debug(' *Tx* >> ', evType, payload);
+ sws.send({
+ event: evType,
+ sid: ++sid,
+ payload: p
+ });
+ } else {
+ $log.warn('sendEvent: no websocket open:', evType, payload);
+ }
+ }
+
+
+ // Handles the specified message using handler bindings.
+ function handleMessage(msgEvent) {
+ var ev;
+ try {
+ ev = JSON.parse(msgEvent.data);
+ $log.debug(' *Rx* >> ', ev.event, ev.payload);
+ dispatchToHandler(ev);
+ } catch (e) {
+ $log.error('message is not valid JSON', msgEvent);
+ }
+ }
+
+ // Dispatches the message to the appropriate handler.
+ function dispatchToHandler(event) {
+ var handler = handlers[event.event];
+ if (handler) {
+ handler(event.payload);
+ } else {
+ $log.warn('unhandled event:', event);
+ }
+ }
+
+ function handleOpen() {
+ $log.info('web socket open');
+ // FIXME: implement calling external hooks
+ }
+
+ function handleClose() {
+ $log.info('web socket closed');
+ // FIXME: implement reconnect logic
}
angular.module('onosRemote')
.factory('WebSocketService',
['$log', '$location', 'UrlFnService', 'FnService',
- function ($log, $loc, ufs, _fs_) {
+ function (_$log_, $loc, ufs, _fs_) {
fs = _fs_;
+ $log = _$log_;
- // creates a web socket for the given path, returning a "handle".
+ // Creates a web socket for the given path, returning a "handle".
// opts contains the event handler callbacks, etc.
function createWebSocket(path, opts) {
var o = opts || {},
@@ -85,8 +128,7 @@
meta: { path: fullUrl, ws: null },
send: send,
close: close
- },
- ws;
+ };
try {
ws = new WebSocket(fullUrl);
@@ -97,23 +139,21 @@
$log.debug('Attempting to open websocket to: ' + fullUrl);
if (ws) {
- ws.onopen = fnOpen(o.onOpen);
- ws.onmessage = fnMessage(o.onMessage);
- ws.onclose = fnClose(o.onClose);
+ ws.onopen = handleOpen;
+ ws.onmessage = handleMessage;
+ ws.onclose = handleClose;
}
- // messages are expected to be event objects..
+ // Sends a formulated event message via the backing web-socket.
function send(ev) {
- if (ev) {
- if (ws) {
- ws.send(JSON.stringify(ev));
- } else {
- $log.warn('ws.send() no web socket open!',
- fullUrl, ev);
- }
+ if (ev && ws) {
+ ws.send(JSON.stringify(ev));
+ } else if (!ws) {
+ $log.warn('ws.send() no web socket open!', fullUrl, ev);
}
}
+ // Closes the backing web-socket.
function close() {
if (ws) {
ws.close();
@@ -122,11 +162,16 @@
}
}
+ sws = api; // Make the shared web-socket accessible
return api;
}
return {
- createWebSocket: createWebSocket
+ resetSid: resetSid,
+ createWebSocket: createWebSocket,
+ bindHandlers: bindHandlers,
+ unbindHandlers: unbindHandlers,
+ sendEvent: sendEvent
};
}]);