(function (exports) { exports.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) { var dataObj = { 'op': 'response', 'id': obj.id, 'error': 'Method not found' } ctx.ws.send(JSON.stringify(dataObj)) return } // Send response var nparams = [].concat(function (data) { var dataObj = { 'op': 'response', 'id': obj.id, 'response': data } ctx.ws.send(JSON.stringify(dataObj)) }, obj.params) this._exports[obj.method].apply(this._exports[obj.method], nparams) break case 'response': ctx._requests[obj.id](obj.response, obj.error) delete ctx._requests[obj.reqId] break } } /** * Call with variadic params */ this.call = function (method) { 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] = (res,err) => { if (err !== undefined) { reject(err) return } resolve(res) } // 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 } })(typeof exports === 'undefined' ? window : exports) // Register directly to window (this)