@acaprojects/a2-composer
Version:
Angular 2 Interface for composer
361 lines • 15 kB
JavaScript
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