X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=test%2FAFB.js;h=4c500b993b21c89c7b98974211f7b4c1c76d6098;hb=056c53da68eaa007a7bcabf77ef3205b6ff04ca1;hp=44b1a9084a89b57c2282f0134242d3c7accaa0b1;hpb=9e3afb8aa598f3e69e2c3723335507c12b4cd1f1;p=src%2Fapp-framework-binder.git diff --git a/test/AFB.js b/test/AFB.js index 44b1a908..4c500b99 100644 --- a/test/AFB.js +++ b/test/AFB.js @@ -1,7 +1,32 @@ +/* + * Copyright (C) 2017-2019 "IoT.bzh" + * Author: José Bollo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ AFB = function(base, initialtoken){ -var urlws = "ws://"+window.location.host+"/"+base; -var urlhttp = "http://"+window.location.host+"/"+base; +if (typeof base != "object") + base = { base: base, token: initialtoken }; + +var initial = { + base: base.base || "api", + token: initialtoken || base.token || URLSearchParams(window.location.search).get('token') || "HELLO", + host: base.host || window.location.host, + url: base.url || undefined +}; + +var urlws = initial.url || "ws://"+initial.host+"/"+initial.base; /*********************************************/ /**** ****/ @@ -11,7 +36,7 @@ var urlhttp = "http://"+window.location.host+"/"+base; var AFB_context; { var UUID = undefined; - var TOKEN = initialtoken; + var TOKEN = initial.token; var context = function(token, uuid) { this.token = token; @@ -41,8 +66,16 @@ var AFB_websocket; var PROTO1 = "x-afb-ws-json1"; - AFB_websocket = function(onopen, onabort) { - this.ws = new WebSocket(urlws, [ PROTO1 ]); + AFB_websocket = function(on_open, on_abort) { + var u = urlws, p = '?'; + if (AFB_context.token) { + u = u + '?x-afb-token=' + AFB_context.token; + p = '&'; + } + if (AFB_context.uuid) + u = u + p + 'x-afb-uuid=' + AFB_context.uuid; + this.ws = new WebSocket(u, [ PROTO1 ]); + this.url = u; this.pendings = {}; this.awaitens = {}; this.counter = 0; @@ -50,8 +83,8 @@ var AFB_websocket; this.ws.onerror = onerror.bind(this); this.ws.onclose = onclose.bind(this); this.ws.onmessage = onmessage.bind(this); - this.onopen = onopen; - this.onabort = onabort; + this.onopen = on_open; + this.onabort = on_abort; } function onerror(event) { @@ -59,7 +92,7 @@ var AFB_websocket; if (f) { delete this.onopen; delete this.onabort; - f && f(this); + f(this); } this.onerror && this.onerror(this); } @@ -72,54 +105,94 @@ var AFB_websocket; } function onclose(event) { + var err = { + jtype: 'afb-reply', + request: { + status: 'disconnected', + info: 'server hung up' + } + }; for (var id in this.pendings) { - var ferr = this.pendings[id].onerror; - ferr && ferr(null, this); + try { this.pendings[id][1](err); } catch (x) {/*NOTHING*/} } this.pendings = {}; this.onclose && this.onclose(); } + function fire(awaitens, name, data) { + var a = awaitens[name]; + if (a) + a.forEach(function(handler){handler(data);}); + var i = name.indexOf("/"); + if (i >= 0) { + a = awaitens[name.substring(0,i)]; + if (a) + a.forEach(function(handler){handler(data);}); + } + a = awaitens["*"]; + if (a) + a.forEach(function(handler){handler(data);}); + } + + function reply(pendings, id, ans, offset) { + if (id in pendings) { + var p = pendings[id]; + delete pendings[id]; + try { p[offset](ans); } catch (x) {/*TODO?*/} + } + } + function onmessage(event) { var obj = JSON.parse(event.data); var code = obj[0]; var id = obj[1]; var ans = obj[2]; AFB_context.token = obj[3]; - var pend; - if (id && id in this.pendings) { - pend = this.pendings[id]; - delete this.pendings[id]; - } switch (code) { - case EVENT: - var a = this.awaitens[id]; - if (a) - a.forEach(function(handler){handler(ans);}); case RETOK: - pend && pend.onsuccess && pend.onsuccess(ans, this); - break; + reply(this.pendings, id, ans, 0); + break; case RETERR: + reply(this.pendings, id, ans, 1); + break; + case EVENT: default: - pend && pend.onerror && pend.onerror(ans, this); - break; + fire(this.awaitens, id, ans); + break; } } function close() { this.ws.close(); + this.ws.onopen = + this.ws.onerror = + this.ws.onclose = + this.ws.onmessage = + this.onopen = + this.onabort = function(){}; } - function call(api, verb, request, onsuccess, onerror) { - var id = String(++this.counter); - this.pendings[id] = { onsuccess: onsuccess, onerror: onerror }; - var arr = [CALL, id, api+"/"+verb, request ]; - if (AFB_context.token) arr.push(AFB_context.token); - this.ws.send(JSON.stringify(arr)); + function call(method, request, callid) { + return new Promise((function(resolve, reject){ + var id, arr; + if (callid) { + id = String(callid); + if (id in this.pendings) + throw new Error("pending callid("+id+") exists"); + } else { + do { + id = String(this.counter = 4095 & (this.counter + 1)); + } while (id in this.pendings); + } + this.pendings[id] = [ resolve, reject ]; + arr = [CALL, id, method, request ]; + if (AFB_context.token) arr.push(AFB_context.token); + this.ws.send(JSON.stringify(arr)); + }).bind(this)); } - function onevent(api, name, handler) { - var id = api+"/"+name; + function onevent(name, handler) { + var id = name; var list = this.awaitens[id] || (this.awaitens[id] = []); list.push(handler); }