|
@@ -1,110 +1,107 @@
|
|
|
+(function (window) {
|
|
|
+ window.WsRpc = function () {
|
|
|
+ var ctx = this
|
|
|
+ this._requests = {}
|
|
|
+ /**
|
|
|
+ * Connect with reconnection
|
|
|
+ */
|
|
|
+ this.connect = function (loc) {
|
|
|
+ var ws = this.ws = new window.WebSocket(loc)
|
|
|
+ ws.onopen = function () {
|
|
|
+ ctx._requests = {}
|
|
|
+ ctx.connected = true
|
|
|
+ if (ctx.onopen !== undefined) {
|
|
|
+ ctx.onopen(ctx)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ws.onmessage = function (evt) {
|
|
|
+ // console.log("RCV:",evt.data)
|
|
|
+ var obj = JSON.parse(evt.data)
|
|
|
+ var arrObj = [].concat(obj) // if object add, if array concat
|
|
|
+ for (var i = 0; i < arrObj.length; i++) {
|
|
|
+ ctx.process(arrObj[i])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ws.onerror = function () { }
|
|
|
+ ws.onclose = function () {
|
|
|
+ if (ctx.connected === true) {
|
|
|
+ ctx.connected = false
|
|
|
+ if (ctx.onclose !== undefined) {
|
|
|
+ ctx.onclose(ctx)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // Retry
|
|
|
+ setTimeout(function () {
|
|
|
+ ctx.connect(loc)
|
|
|
+ }, 3000) // 3 seconds reconnect
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Process requests
|
|
|
+ */
|
|
|
+ this.process = function (obj) {
|
|
|
+ switch (obj.op) {
|
|
|
+ case 'call':
|
|
|
+ if (obj.method === undefined || this._exports[obj.method] === undefined) {
|
|
|
+ // TODO: Send object to inform error
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Send response
|
|
|
+ var nparams = [].concat((data) => {
|
|
|
+ var dataObj = {
|
|
|
+ 'op': 'response',
|
|
|
+ 'id': obj.id,
|
|
|
+ 'response': data
|
|
|
+ }
|
|
|
+ ctx.ws.send(JSON.stringify(dataObj))
|
|
|
+ }, obj.param)
|
|
|
+ this._exports[obj.method].apply(this._exports[obj.method], nparams)
|
|
|
+ break
|
|
|
+ case 'response':
|
|
|
+ ctx._requests[obj.id](obj.response)
|
|
|
+ delete ctx._requests[obj.reqId]
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-/*
|
|
|
- Goal having something like:
|
|
|
-
|
|
|
- wsrpc.Connect("/ws");
|
|
|
- wsrpc.Connect("ws://127.0.0.1/ws");
|
|
|
-
|
|
|
-
|
|
|
- obj = {
|
|
|
- method1:function() {
|
|
|
- //Hello
|
|
|
- }
|
|
|
- }
|
|
|
- wsrpc.Export(obj);
|
|
|
- */
|
|
|
-
|
|
|
-function WsRpc() {
|
|
|
- var ctx = this
|
|
|
- this._requests = {}
|
|
|
- this.connect = function(loc) {
|
|
|
- var ws = this.ws = new WebSocket(loc)
|
|
|
- ws.onopen = function() {
|
|
|
- ctx._requests = {}
|
|
|
- ctx.connected = true;
|
|
|
- if(ctx.onopen != undefined) {
|
|
|
- ctx.onopen(ctx)
|
|
|
- }
|
|
|
- }
|
|
|
- ws.onmessage = function(evt) {
|
|
|
- //console.log("RCV:",evt.data)
|
|
|
- var obj = JSON.parse(evt.data)
|
|
|
- var arrObj = [].concat(obj); // if object add, if array concat
|
|
|
- for( var i = 0; i <arrObj.length; i++) {
|
|
|
- ctx.process(arrObj[i]);
|
|
|
- }
|
|
|
- }
|
|
|
- ws.onerror = function() { }
|
|
|
- ws.onclose = function() {
|
|
|
- if(ctx.connected == true) {
|
|
|
- ctx.connected = false;
|
|
|
- if(ctx.onclose != undefined) {
|
|
|
- ctx.onclose(ctx)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Retry
|
|
|
- setTimeout(function() {
|
|
|
- ctx.connect(loc)
|
|
|
- },3000) // 3 seconds reconnect
|
|
|
- }
|
|
|
- }
|
|
|
- this.process = function(obj) {
|
|
|
- if (obj.op == "call") {
|
|
|
- if(obj.method == undefined || this._exports[obj.method] == undefined) {
|
|
|
- //TODO: Send objet to inform error
|
|
|
- return
|
|
|
- }
|
|
|
- function response(data) {
|
|
|
- var dataObj = {
|
|
|
- "op":"response",
|
|
|
- "reqId":obj.reqId,
|
|
|
- "data":data
|
|
|
- }
|
|
|
- ctx.ws.send(JSON.stringify(dataObj));
|
|
|
- }
|
|
|
- var nparams = [].concat(response,obj.param)
|
|
|
- this._exports[obj.method].apply(this._exports[obj.method],nparams)
|
|
|
- }
|
|
|
- if( obj.op == "response" ) {
|
|
|
- //console.log("Receiving response for:", obj.reqId)
|
|
|
- ctx._requests[obj.reqId](obj.data)
|
|
|
- delete ctx._requests[obj.reqId]
|
|
|
- }
|
|
|
- }
|
|
|
- this.call = function(method) {
|
|
|
- var aparam = Array.prototype.slice.call(arguments,1)
|
|
|
- return new Promise(function(resolve,reject) {
|
|
|
- if(ctx.connected == false ) {
|
|
|
- reject(Error("Not connected"))
|
|
|
- }
|
|
|
-
|
|
|
- var uuidStr = uuid();
|
|
|
- var callObj = {
|
|
|
- "reqId":uuidStr,
|
|
|
- "op":"call",
|
|
|
- "method":method,
|
|
|
- "param":aparam
|
|
|
- }
|
|
|
- ctx._requests[uuidStr] = resolve;
|
|
|
- //console.log("Sending a call:", method)
|
|
|
- ctx.ws.send(JSON.stringify(callObj));
|
|
|
- })
|
|
|
- }
|
|
|
- this.export = function(obj){
|
|
|
- this._exports = obj;
|
|
|
- }
|
|
|
-
|
|
|
- return this
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-function uuid() {
|
|
|
- var ret = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
|
- var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
|
|
- return v.toString(16);
|
|
|
- });
|
|
|
- return ret;
|
|
|
-}
|
|
|
+ /**
|
|
|
+ * Call with variadic params
|
|
|
+ */
|
|
|
+ this.call = function (method, ...params) {
|
|
|
+ // var aparam = Array.prototype.slice.call(arguments, 1)
|
|
|
+ var aparam = params
|
|
|
+ return new Promise(function (resolve, reject) {
|
|
|
+ if (ctx.connected === false) {
|
|
|
+ reject(Error('Not connected'))
|
|
|
+ }
|
|
|
|
|
|
+ var uuidStr = uuid()
|
|
|
+ var callObj = {
|
|
|
+ 'op': 'call',
|
|
|
+ 'id': uuidStr,
|
|
|
+ 'method': method,
|
|
|
+ 'params': aparam
|
|
|
+ }
|
|
|
+ ctx._requests[uuidStr] = resolve
|
|
|
+ // console.log("Sending a call:", method)
|
|
|
+ ctx.ws.send(JSON.stringify(callObj)) // if error delete request
|
|
|
+ })
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Export function, binds export methods
|
|
|
+ */
|
|
|
+ this.export = function (obj) {
|
|
|
+ this._exports = obj
|
|
|
+ }
|
|
|
|
|
|
+ return this
|
|
|
+ }
|
|
|
+ function uuid () {
|
|
|
+ var ret = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
|
+ var r = Math.random() * 16 | 0
|
|
|
+ var v = c === 'x' ? r : (r & 0x3 | 0x8)
|
|
|
+ return v.toString(16)
|
|
|
+ })
|
|
|
+ return ret
|
|
|
+ }
|
|
|
+})(window)
|