123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- (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) {
- // 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.params)
- 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
- }
- }
- /**
- * 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
- }
- })(typeof exports === 'undefined' ? window : exports) // Register directly to window (this)
|