UNPKG

@acaprojects/a2-composer

Version:
361 lines 15 kB
import { COMPOSER } from '../settings'; var BIND = 'bind'; var UNBIND = 'unbind'; var DEBUG = 'debug'; var IGNORE = 'ignore'; var PONG = 'pong'; var EXEC = 'exec'; var SUCCESS = 'success'; var ERROR = 'error'; var NOTIFY = 'notify'; var SECONDS = 1000; var RECONNECT_TIMER = 5 * SECONDS; var KEEP_ALIVE_TIMER = 60 * SECONDS; var WebSocketInterface = (function () { function WebSocketInterface(srv, auth, fixed, host, port) { if (fixed === void 0) { fixed = false; } this.io = null; this.req_id = 0; this.session_id = ''; this.connected = false; this.reconnected = false; this.connect_check = null; this.connect_promise = null; this.requests = {}; this.fixed = false; this.session_id = Math.floor(Math.random() * 89999 + 10000).toString(); if (!host) { host = location.hostname; } if (!port) { port = location.port; } this.fixed = fixed; this.serv = srv; this.setup(auth, host, port); } WebSocketInterface.prototype.setup = function (auth, host, port, protocol) { if (!host) { host = location.hostname; } if (!port) { port = location.port; } if (!protocol) { port = location.protocol; } this.auth = auth; var prot = (protocol === 'https:' ? 'wss://' : 'ws://'); var use_port = (port === '80' || port === '443' || !port ? '' : (':' + port)); this.end_point = prot + host + use_port; this.uri = this.end_point + '/control/websocket'; }; WebSocketInterface.prototype.bind = function (sys_id, mod_id, i, name, callback) { var _this = this; return new Promise(function (resolve, reject) { _this.sendRequest(BIND, sys_id, mod_id, i, name, null) .then(function (id) { _this.requests[id] = { resolve: resolve, reject: reject, }; }); }); }; WebSocketInterface.prototype.unbind = function (sys_id, mod_id, i, name, callback) { var _this = this; return new Promise(function (resolve, reject) { _this.sendRequest(UNBIND, sys_id, mod_id, i, name, null) .then(function (id) { _this.requests[id] = { resolve: resolve, reject: reject, }; }); }); }; WebSocketInterface.prototype.exec = function (sys_id, mod_id, i, fn, args) { var _this = this; return new Promise(function (resolve, reject) { _this.sendRequest(EXEC, sys_id, mod_id, i, fn, args) .then(function (id) { _this.requests[id] = { resolve: resolve, reject: reject, }; }); }); }; WebSocketInterface.prototype.debug = function (sys_id, mod_id, i) { return this.sendRequest(DEBUG, sys_id, mod_id, i, DEBUG); }; WebSocketInterface.prototype.ignore = function (sys_id, mod_id, inst) { return this.sendRequest(IGNORE, sys_id, mod_id, null, IGNORE); }; WebSocketInterface.prototype.connect = function (tries) { var _this = this; if (tries === void 0) { tries = 0; } if (!this.connect_promise) { this.connect_promise = new Promise(function (resolve, reject) { if (tries > 10) { reject(); } if (_this.io && _this.io.readyState !== _this.io.CLOSED) { if (_this.io.readyState === _this.io.CONNECTING) { reject({ message: 'Already attempting to connect to websocket.' }); _this.connect_promise = null; return; } else if (_this.io.readyState === _this.io.OPEN) { _this.connected = true; _this.connect_promise = null; resolve(); return; } else if (_this.io.readyState === _this.io.CLOSING) { _this.connect_promise = null; reject({ message: 'Websocket is closing' }); return; } } else { if (_this.auth) { _this.auth.getToken().then(function (token) { COMPOSER.log('WS', "Retrieved token '" + token + "'"); if (token) { var uri = _this.uri; uri += '?bearer_token=' + token; if (_this.fixed) { uri += '&fixed_device=true'; } var search = location.search; if (search.indexOf('fixed_device') >= 0) { uri += '&fixed_device=true'; } COMPOSER.log('WS', 'Building websocket...'); _this.io = new WebSocket(uri); _this.io.onmessage = function (evt) { _this.onmessage(evt); }; _this.io.onclose = function (evt) { _this.onclose(evt); }; _this.io.onopen = function (evt) { _this.onopen(evt); setTimeout(function () { _this.connected = true; resolve(); _this.connect_promise = null; }, 100); }; _this.io.onerror = function (evt) { _this.serv.r.checkAuth(); _this.io = null; if (!_this.connected) { COMPOSER.error('WS', 'Websocket Error:', evt); reject(); _this.connect_promise = null; } }; } else { setTimeout(function () { _this.connect(++tries).then(function () { resolve(); }, function () { reject(); }); }, 200); } }); } else { _this.io = new WebSocket(_this.uri); _this.io.onmessage = function (evt) { _this.onmessage(evt); }; _this.io.onclose = function (evt) { _this.onclose(evt); }; _this.io.onopen = function (evt) { _this.onopen(evt); setTimeout(function () { _this.connected = true; resolve(); _this.connect_promise = null; }, 100); }; _this.io.onerror = function (evt) { _this.serv.r.checkAuth(); _this.io = null; COMPOSER.error('WS', 'Websocket Error:', evt); reject(); _this.connect_promise = null; }; } } }); } return this.connect_promise; }; WebSocketInterface.prototype.reconnect = function () { var _this = this; if (this.io === null || this.io.readyState === this.io.CLOSED && !this.connect_promise) { COMPOSER.log('WS', 'Reconnecting websocket...'); this.connect().then(function () { _this.serv.rebind(); return; }, function () { return; }); this.reconnected = true; } }; WebSocketInterface.prototype.startKeepAlive = function () { var _this = this; this.keepAliveInterval = setInterval(function () { if (_this.io) { _this.io.send('ping'); } }, KEEP_ALIVE_TIMER); }; WebSocketInterface.prototype.stopKeepAlive = function () { clearInterval(this.keepAliveInterval); }; WebSocketInterface.prototype.onopen = function (evt) { var _this = this; COMPOSER.log('WS', 'Websocket connected'); this.connect_promise = null; this.startKeepAlive(); if (this.reconnected) { this.serv.rebind(); } this.reconnected = false; if (!this.connect_check) { this.connect_check = setInterval(function () { _this.reconnect(); }, RECONNECT_TIMER); } }; WebSocketInterface.prototype.onclose = function (evt) { this.connected = false; COMPOSER.log('WS', 'Websocket closed'); this.connect_promise = null; this.io = null; this.stopKeepAlive(); }; WebSocketInterface.prototype.onmessage = function (evt) { var msg; var meta; var system; var module; var binding; if (evt.data === PONG || !evt.data) { return; } else { msg = JSON.parse(evt.data); } if (msg.type === SUCCESS || msg.type === ERROR || msg.type === NOTIFY) { meta = msg.meta; var meta_list = ''; if (meta) { meta_list = meta.sys + ", " + meta.mod + " " + meta.index + ", " + meta.name; } if (msg.type === ERROR) { COMPOSER.error('WS', "Received error(" + msg.id + "). " + msg.msg); } else if (msg.type === NOTIFY) { COMPOSER.log("WS", "Received notify. " + meta_list + " \u2192", msg.value); } else { if (meta) { COMPOSER.log("WS", "Received success(" + msg.id + "). " + meta_list); } else { COMPOSER.log("WS", "Received success(" + msg.id + "). Value: " + msg.value); } } if (msg.type === SUCCESS) { if (this.requests[msg.id] && this.requests[msg.id].resolve) { this.requests[msg.id].resolve(msg.value); } } else if (msg.type === ERROR) { if (this.requests[msg.id] && this.requests[msg.id].reject) { this.requests[msg.id].reject(msg.msg); } } if (this.requests[msg.id]) { delete this.requests[msg.id]; } if (meta) { system = this.serv.get(meta.sys); if (!system) { return this.fail(msg, 'system'); } module = system.get(meta.mod, meta.index); if (!module) { return this.fail(msg, 'module'); } binding = module.get(meta.name); if (!binding) { return this.fail(msg, 'binding'); } else { binding[msg.type](msg); } } } else if (msg.type === 'debug') { return true; } return true; }; WebSocketInterface.prototype.fail = function (msg, type) { COMPOSER.error('WS', "Failed " + type + ". " + JSON.stringify(msg)); return false; }; WebSocketInterface.prototype.sendRequest = function (type, system, mod, index, name, args) { var _this = this; if (args === void 0) { args = []; } return new Promise(function (resolve) { if (!_this.io || _this.io.readyState !== _this.io.OPEN) { if (!WebSocketInterface.retries["[" + type + "] " + system + ", " + mod + " " + index + ", " + name]) { WebSocketInterface.retries["[" + type + "] " + system + ", " + mod + " " + index + ", " + name] = 0; } _this.connect().then(function () { setTimeout(function () { _this.sendRequest(type, system, mod, index, name, args) .then(function (id) { resolve(id); }); }, 200); WebSocketInterface.retries["[" + type + "] " + system + ", " + mod + " " + index + ", " + name] = 0; }, function (err) { var error = err ? err.message : 'No error message'; COMPOSER.log('WS', "Failed to connect(" + type + ", " + name + "). " + error); WebSocketInterface.retries["[" + type + "] " + system + ", " + mod + " " + index + ", " + name]++; if (WebSocketInterface.retries["[" + type + "] " + system + ", " + mod + " " + index + ", " + name] > 10) { resolve(-1); } setTimeout(function () { _this.sendRequest(type, system, mod, index, name, args) .then(function (id) { resolve(id); }); }, 500 * WebSocketInterface.retries["[" + type + "] " + system + ", " + mod + " " + index + ", " + name]); }); return; } _this.req_id += 1; if (!(args instanceof Array)) { args = [args]; } var request = { id: _this.session_id + "_" + _this.req_id, cmd: type, sys: system, mod: mod, index: index, name: name, args: args, }; COMPOSER.log('WS', "Sent " + type + " request(" + request.id + "). " + system + ", " + mod + ", " + index + ", " + name, args); if (args !== null) { request.args = args; } _this.io.send(JSON.stringify(request)); resolve(request.id); }); }; return WebSocketInterface; }()); export { WebSocketInterface }; WebSocketInterface.retries = {}; export var $WebSocket = WebSocketInterface; //# sourceMappingURL=websocket.js.map