diff options
author | Jan-Simon Möller <jsmoeller@linuxfoundation.org> | 2022-01-26 12:25:31 +0100 |
---|---|---|
committer | Jan-Simon Moeller <jsmoeller@linuxfoundation.org> | 2022-02-02 11:50:02 +0000 |
commit | 8160b5cdc8547277f3f31ee1e41524754d5d987d (patch) | |
tree | 6ebbcfa9802c82de6b552733ef53d411247e1cdd /docs/3_Developer_Guides/2_Application_Framework_Binder/Annexes/2_WebSocket_protocol_x-afb-ws-json1.md | |
parent | 835363f430c5dee0b53b7c415572cdfdcc02ad18 (diff) |
Update to documentation before Marlinmarlin_12.92.0marlin/12.92.012.92.0
This is mostly a cleanup before the Magic Marlin Release.
We do have the Application Framework chapter rewrite pending.
Bug-AGL: SPEC-4236
Signed-off-by: Jan-Simon Möller <jsmoeller@linuxfoundation.org>
Change-Id: I7e1f39667b4db417497b1d0c84065c173fa18439
Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/documentation/+/27097
Diffstat (limited to 'docs/3_Developer_Guides/2_Application_Framework_Binder/Annexes/2_WebSocket_protocol_x-afb-ws-json1.md')
-rw-r--r-- | docs/3_Developer_Guides/2_Application_Framework_Binder/Annexes/2_WebSocket_protocol_x-afb-ws-json1.md | 308 |
1 files changed, 0 insertions, 308 deletions
diff --git a/docs/3_Developer_Guides/2_Application_Framework_Binder/Annexes/2_WebSocket_protocol_x-afb-ws-json1.md b/docs/3_Developer_Guides/2_Application_Framework_Binder/Annexes/2_WebSocket_protocol_x-afb-ws-json1.md deleted file mode 100644 index 7ebf22a..0000000 --- a/docs/3_Developer_Guides/2_Application_Framework_Binder/Annexes/2_WebSocket_protocol_x-afb-ws-json1.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -title: WebSocket protocol x-afb-ws-json1 ---- - -The WebSocket protocol *x-afb-ws-json1* is used to communicate between -an application and a binder. It allows access to all registered apis -of the binder. - -This protocol is inspired from the protocol **OCPP - SRPC** as described for -example here: -[OCPP transport specification - SRPC over WebSocket](http://www.gir.fr/ocppjs/ocpp_srpc_spec.shtml). - -The registration to the IANA is still to be done, see: -[WebSocket Protocol Registries](https://www.iana.org/assignments/websocket/websocket.xml) - -This document gives a short description of the protocol *x-afb-ws-json1*. -A more formal description has to be done. - -## Architecture - -The protocol is intended to be symmetric. It allows: - -- to CALL a remote procedure that returns a result -- to push and receive EVENT - -## Messages - -Valid messages are made of *text* frames that are all valid JSON. - -Valid messages are: - -Calls: - -```txt -[ 2, ID, PROCN, ARGS ] -[ 2, ID, PROCN, ARGS, TOKEN ] -``` - -Replies (3: OK, 4: ERROR): - -```txt -[ 3, ID, RESP ] -[ 4, ID, RESP ] -``` - -Events: - -```txt -[ 5, EVTN, OBJ ] -``` - -Where: - -| Field | Type | Description -|-------|--------|------------------ -| ID | string | A string that identifies the call. A reply to that call use the ID of the CALL. -| PROCN | string | The procedure name to call of the form "api/verb" -| ARGS | any | Any argument to pass to the call (see afb_req_json that returns it) -| RESP | any | The response to the call -| TOKEN | string | The authorisation token -| EVTN | string | Name of the event in the form "api/event" -| OBJ | any | The companion object of the event - -Below, an example of exchange: - -```txt -C->S: [2,"156","hello/ping",null] -S->C: [3,"156",{"response":"Some String","jtype":"afb-reply","request":{"status":"success","info":"Ping Binder Daemon tag=pingSample count=1 query=\"null\"","uuid":"ec30120c-6997-4529-9d63-c0de0cce56c0"}}] -``` - -## History - -### 14 November 2019 - -Removal of token returning. The replies - -```txt -[ 3, ID, RESP, TOKEN ] -[ 4, ID, RESP, TOKEN ] -``` - -are removed from the specification. - -## Future - -Here are the planned extensions: - -- add binary messages with cbor data -- add calls with unstructured replies - -This could be implemented by extending the current protocol or by -allowing the binder to accept either protocol including the new ones. - -## Javascript implementation - -The file **AFB.js** is a javascript implementation of the protocol. - -Here is that code: - -```javascript -/* - * Copyright (C) 2017-2019 "IoT.bzh" - * Author: José Bollo <jose.bollo@iot.bzh> - * - * 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){ - -if (typeof base != "object") - base = { base: base, token: initialtoken }; - -var initial = { - base: base.base || "api", - token: base.token || initialtoken || "HELLO", - host: base.host || window.location.host, - url: base.url || undefined -}; - -var urlws = initial.url || "ws://"+initial.host+"/"+initial.base; - -/*********************************************/ -/**** ****/ -/**** AFB_context ****/ -/**** ****/ -/*********************************************/ -var AFB_context; -{ - var UUID = undefined; - var TOKEN = initial.token; - - var context = function(token, uuid) { - this.token = token; - this.uuid = uuid; - } - - context.prototype = { - get token() {return TOKEN;}, - set token(tok) {if(tok) TOKEN=tok;}, - get uuid() {return UUID;}, - set uuid(id) {if(id) UUID=id;} - }; - - AFB_context = new context(); -} -/*********************************************/ -/**** ****/ -/**** AFB_websocket ****/ -/**** ****/ -/*********************************************/ -var AFB_websocket; -{ - var CALL = 2; - var RETOK = 3; - var RETERR = 4; - var EVENT = 5; - - var PROTO1 = "x-afb-ws-json1"; - - AFB_websocket = function(on_open, on_abort) { - var u = urlws; - if (AFB_context.token) { - u = u + '?x-afb-token=' + AFB_context.token; - if (AFB_context.uuid) - u = u + '&x-afb-uuid=' + AFB_context.uuid; - } - this.ws = new WebSocket(u, [ PROTO1 ]); - this.url = u; - this.pendings = {}; - this.awaitens = {}; - this.counter = 0; - this.ws.onopen = onopen.bind(this); - this.ws.onerror = onerror.bind(this); - this.ws.onclose = onclose.bind(this); - this.ws.onmessage = onmessage.bind(this); - this.onopen = on_open; - this.onabort = on_abort; - } - - function onerror(event) { - var f = this.onabort; - if (f) { - delete this.onopen; - delete this.onabort; - f && f(this); - } - this.onerror && this.onerror(this); - } - - function onopen(event) { - var f = this.onopen; - delete this.onopen; - delete this.onabort; - f && f(this); - } - - function onclose(event) { - for (var id in this.pendings) { - try { this.pendings[id][1](); } catch (x) {/*TODO?*/} - } - 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]; - switch (code) { - case RETOK: - reply(this.pendings, id, ans, 0); - break; - case RETERR: - reply(this.pendings, id, ans, 1); - break; - case EVENT: - default: - 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(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(name, handler) { - var id = name; - var list = this.awaitens[id] || (this.awaitens[id] = []); - list.push(handler); - } - - AFB_websocket.prototype = { - close: close, - call: call, - onevent: onevent - }; -} -/*********************************************/ -/**** ****/ -/**** ****/ -/**** ****/ -/*********************************************/ -return { - context: AFB_context, - ws: AFB_websocket -}; -}; -``` |