GUI -- Added websock open listeners mechanism.
- made event handler structure parsing a little cleverer. Change-Id: I15120dabd0aade28e6ee3680faf96f408aed1450
Showing
3 changed files
with
64 additions
and
18 deletions
... | @@ -30,10 +30,13 @@ | ... | @@ -30,10 +30,13 @@ |
30 | sid = 0, // event sequence identifier | 30 | sid = 0, // event sequence identifier |
31 | handlers = {}, // event handler bindings | 31 | handlers = {}, // event handler bindings |
32 | pendingEvents = [], // events TX'd while socket not up | 32 | pendingEvents = [], // events TX'd while socket not up |
33 | + host, // web socket host | ||
33 | url, // web socket URL | 34 | url, // web socket URL |
34 | clusterNodes = [], // ONOS instances data for failover | 35 | clusterNodes = [], // ONOS instances data for failover |
35 | clusterIndex = -1, // the instance to which we are connected | 36 | clusterIndex = -1, // the instance to which we are connected |
36 | - connectRetries = 0; | 37 | + connectRetries = 0, // limit our attempts at reconnecting |
38 | + openListeners = {}, // registered listeners for websocket open() | ||
39 | + nextListenerId = 1; // internal ID for open listeners | ||
37 | 40 | ||
38 | // ======================= | 41 | // ======================= |
39 | // === Bootstrap Handler | 42 | // === Bootstrap Handler |
... | @@ -55,7 +58,7 @@ | ... | @@ -55,7 +58,7 @@ |
55 | // === Web socket callbacks | 58 | // === Web socket callbacks |
56 | 59 | ||
57 | function handleOpen() { | 60 | function handleOpen() { |
58 | - $log.info('Web socket open'); | 61 | + $log.info('Web socket open - ', url); |
59 | vs.hide(); | 62 | vs.hide(); |
60 | 63 | ||
61 | $log.debug('Sending ' + pendingEvents.length + ' pending event(s)...'); | 64 | $log.debug('Sending ' + pendingEvents.length + ' pending event(s)...'); |
... | @@ -66,6 +69,7 @@ | ... | @@ -66,6 +69,7 @@ |
66 | 69 | ||
67 | connectRetries = 0; | 70 | connectRetries = 0; |
68 | wsUp = true; | 71 | wsUp = true; |
72 | + informListeners(host, url); | ||
69 | } | 73 | } |
70 | 74 | ||
71 | // Handles the specified (incoming) message using handler bindings. | 75 | // Handles the specified (incoming) message using handler bindings. |
... | @@ -78,7 +82,7 @@ | ... | @@ -78,7 +82,7 @@ |
78 | $log.error('Message.data is not valid JSON', msgEvent.data, e); | 82 | $log.error('Message.data is not valid JSON', msgEvent.data, e); |
79 | return; | 83 | return; |
80 | } | 84 | } |
81 | - $log.debug(' *Rx* >> ', ev.event, ev.payload); | 85 | + $log.debug(' << *Rx* ', ev.event, ev.payload); |
82 | 86 | ||
83 | if (h = handlers[ev.event]) { | 87 | if (h = handlers[ev.event]) { |
84 | try { | 88 | try { |
... | @@ -129,12 +133,17 @@ | ... | @@ -129,12 +133,17 @@ |
129 | return ip; | 133 | return ip; |
130 | } | 134 | } |
131 | 135 | ||
136 | + function informListeners(host, url) { | ||
137 | + angular.forEach(openListeners, function(lsnr) { | ||
138 | + lsnr.cb(host, url); | ||
139 | + }); | ||
140 | + } | ||
141 | + | ||
132 | function _send(ev) { | 142 | function _send(ev) { |
133 | $log.debug(' *Tx* >> ', ev.event, ev.payload); | 143 | $log.debug(' *Tx* >> ', ev.event, ev.payload); |
134 | ws.send(JSON.stringify(ev)); | 144 | ws.send(JSON.stringify(ev)); |
135 | } | 145 | } |
136 | 146 | ||
137 | - | ||
138 | // =================== | 147 | // =================== |
139 | // === API Functions | 148 | // === API Functions |
140 | 149 | ||
... | @@ -145,12 +154,14 @@ | ... | @@ -145,12 +154,14 @@ |
145 | 154 | ||
146 | // Currently supported opts: | 155 | // Currently supported opts: |
147 | // wsport: web socket port (other than default 8181) | 156 | // wsport: web socket port (other than default 8181) |
148 | - // server: if defined, is the server address to use | 157 | + // host: if defined, is the host address to use |
149 | - function createWebSocket(opts, server) { | 158 | + function createWebSocket(opts, _host_) { |
150 | var wsport = (opts && opts.wsport) || null; | 159 | var wsport = (opts && opts.wsport) || null; |
160 | + | ||
151 | webSockOpts = opts; // preserved for future calls | 161 | webSockOpts = opts; // preserved for future calls |
152 | 162 | ||
153 | - url = ufs.wsUrl('core', wsport, server); | 163 | + host = _host_ || $loc.host(); |
164 | + url = ufs.wsUrl('core', wsport, _host_); | ||
154 | 165 | ||
155 | $log.debug('Attempting to open websocket to: ' + url); | 166 | $log.debug('Attempting to open websocket to: ' + url); |
156 | ws = wsock.newWebSocket(url); | 167 | ws = wsock.newWebSocket(url); |
... | @@ -163,15 +174,18 @@ | ... | @@ -163,15 +174,18 @@ |
163 | return url; | 174 | return url; |
164 | } | 175 | } |
165 | 176 | ||
166 | - // Binds the specified message handlers. | 177 | + // Binds the message handlers to their message type (event type) as |
167 | - // keys are the event IDs | 178 | + // specified in the given map. Note that keys are the event IDs; values |
168 | - // values are the API on which the handler function is a property | 179 | + // are either: |
180 | + // * the event handler function, or | ||
181 | + // * an API object which has an event handler for the key | ||
182 | + // | ||
169 | function bindHandlers(handlerMap) { | 183 | function bindHandlers(handlerMap) { |
170 | var m = d3.map(handlerMap), | 184 | var m = d3.map(handlerMap), |
171 | dups = []; | 185 | dups = []; |
172 | 186 | ||
173 | m.forEach(function (eventId, api) { | 187 | m.forEach(function (eventId, api) { |
174 | - var fn = fs.isF(api[eventId]); | 188 | + var fn = fs.isF(api) || fs.isF(api[eventId]); |
175 | if (!fn) { | 189 | if (!fn) { |
176 | $log.warn(eventId + ' handler not a function'); | 190 | $log.warn(eventId + ' handler not a function'); |
177 | return; | 191 | return; |
... | @@ -198,6 +212,28 @@ | ... | @@ -198,6 +212,28 @@ |
198 | }); | 212 | }); |
199 | } | 213 | } |
200 | 214 | ||
215 | + function addOpenListener(callback) { | ||
216 | + var id = nextListenerId++, | ||
217 | + cb = fs.isF(callback), | ||
218 | + o = { id: id, cb: cb }; | ||
219 | + | ||
220 | + if (cb) { | ||
221 | + openListeners[id] = o; | ||
222 | + } else { | ||
223 | + $log.error('WSS.addOpenListener(): callback not a function'); | ||
224 | + o.error = 'No callback defined'; | ||
225 | + } | ||
226 | + return o; | ||
227 | + } | ||
228 | + | ||
229 | + function removeOpenListener(lsnr) { | ||
230 | + var id = lsnr && lsnr.id, | ||
231 | + o = openListeners[id]; | ||
232 | + if (o) { | ||
233 | + delete openListeners[id]; | ||
234 | + } | ||
235 | + } | ||
236 | + | ||
201 | // Formulates an event message and sends it via the web-socket. | 237 | // Formulates an event message and sends it via the web-socket. |
202 | // If the websocket is not up yet, we store it in a pending list. | 238 | // If the websocket is not up yet, we store it in a pending list. |
203 | function sendEvent(evType, payload) { | 239 | function sendEvent(evType, payload) { |
... | @@ -230,17 +266,15 @@ | ... | @@ -230,17 +266,15 @@ |
230 | wsock = _wsock_; | 266 | wsock = _wsock_; |
231 | vs = _vs_; | 267 | vs = _vs_; |
232 | 268 | ||
233 | - // TODO: Consider how to simplify handler structure | 269 | + bindHandlers(builtinHandlers); |
234 | - // Now it is an object of key -> object that has a method named 'key'. | ||
235 | - bindHandlers({ | ||
236 | - bootstrap: builtinHandlers | ||
237 | - }); | ||
238 | 270 | ||
239 | return { | 271 | return { |
240 | resetSid: resetSid, | 272 | resetSid: resetSid, |
241 | createWebSocket: createWebSocket, | 273 | createWebSocket: createWebSocket, |
242 | bindHandlers: bindHandlers, | 274 | bindHandlers: bindHandlers, |
243 | unbindHandlers: unbindHandlers, | 275 | unbindHandlers: unbindHandlers, |
276 | + addOpenListener: addOpenListener, | ||
277 | + removeOpenListener: removeOpenListener, | ||
244 | sendEvent: sendEvent | 278 | sendEvent: sendEvent |
245 | }; | 279 | }; |
246 | } | 280 | } | ... | ... |
... | @@ -30,7 +30,8 @@ | ... | @@ -30,7 +30,8 @@ |
30 | var $log, wss, tps, tis, tfs, tss, tts; | 30 | var $log, wss, tps, tis, tfs, tss, tts; |
31 | 31 | ||
32 | // internal state | 32 | // internal state |
33 | - var handlerMap; | 33 | + var handlerMap, |
34 | + openListener; | ||
34 | 35 | ||
35 | // ========================== | 36 | // ========================== |
36 | 37 | ||
... | @@ -58,6 +59,14 @@ | ... | @@ -58,6 +59,14 @@ |
58 | }; | 59 | }; |
59 | } | 60 | } |
60 | 61 | ||
62 | + function wsOpen(host, url) { | ||
63 | + $log.debug('TOPO: web socket open - cluster node:', host, 'URL:', url); | ||
64 | + | ||
65 | + // TODO: request "instanceUpdate" events for all instances | ||
66 | + // this should give us the updated uiAttached icon placement | ||
67 | + | ||
68 | + } | ||
69 | + | ||
61 | angular.module('ovTopo') | 70 | angular.module('ovTopo') |
62 | .factory('TopoEventService', | 71 | .factory('TopoEventService', |
63 | ['$log', '$location', 'WebSocketService', | 72 | ['$log', '$location', 'WebSocketService', |
... | @@ -76,6 +85,7 @@ | ... | @@ -76,6 +85,7 @@ |
76 | createHandlerMap(); | 85 | createHandlerMap(); |
77 | 86 | ||
78 | function start() { | 87 | function start() { |
88 | + openListener = wss.addOpenListener(wsOpen); | ||
79 | wss.bindHandlers(handlerMap); | 89 | wss.bindHandlers(handlerMap); |
80 | wss.sendEvent('topoStart'); | 90 | wss.sendEvent('topoStart'); |
81 | wss.sendEvent('requestSummary'); | 91 | wss.sendEvent('requestSummary'); |
... | @@ -85,6 +95,8 @@ | ... | @@ -85,6 +95,8 @@ |
85 | function stop() { | 95 | function stop() { |
86 | wss.sendEvent('topoStop'); | 96 | wss.sendEvent('topoStop'); |
87 | wss.unbindHandlers(handlerMap); | 97 | wss.unbindHandlers(handlerMap); |
98 | + wss.removeOpenListener(openListener); | ||
99 | + openListener = null; | ||
88 | $log.debug('topo comms stopped'); | 100 | $log.debug('topo comms stopped'); |
89 | } | 101 | } |
90 | 102 | ... | ... |
... | @@ -46,7 +46,7 @@ describe('factory: fw/remote/websocket.js', function () { | ... | @@ -46,7 +46,7 @@ describe('factory: fw/remote/websocket.js', function () { |
46 | it('should define api functions', function () { | 46 | it('should define api functions', function () { |
47 | expect(fs.areFunctions(wss, [ | 47 | expect(fs.areFunctions(wss, [ |
48 | 'resetSid', 'createWebSocket', 'bindHandlers', 'unbindHandlers', | 48 | 'resetSid', 'createWebSocket', 'bindHandlers', 'unbindHandlers', |
49 | - 'sendEvent' | 49 | + 'addOpenListener', 'removeOpenListener', 'sendEvent' |
50 | ])).toBeTruthy(); | 50 | ])).toBeTruthy(); |
51 | }); | 51 | }); |
52 | 52 | ... | ... |
-
Please register or login to post a comment