teoclits
Version:
Typescript angular Teonet Client module
599 lines • 21.2 kB
JavaScript
/*
* The MIT License
*
* Copyright 2017 Kirill Scherba <kirill@scherba.ru>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { Injectable } from '@angular/core';
import { TeonetAuth } from './teocli.auth';
import { TeocliRTC } from './teocli.webrtc';
;
export var Teonet = {
peer: {
l0: 'ps-server',
auth: 'teo-auth'
},
status: {
offline: 0,
connecting: 1,
logining: 2,
online: 3
}
};
var TeonetCli = /** @class */ (function (_super) {
__extends(TeonetCli, _super);
function TeonetCli() {
var _this = this;
console.debug("TeonetCli::constructor");
var connect_url = 'ws://' + 'teomac.ksproject.org:80' + '/ws';
var ws = new WebSocket(connect_url);
_this = _super.call(this, ws) || this;
_this.status = Teonet.status.connecting;
_this.isTeonetClientsActiveFunc = function () { return true; };
_this.connect_url = connect_url;
_this.RECONNECT_TIMEOUT = 1000;
_this.INIT_TIMEOUT = 7000;
_this.inited = false;
_this.eventSubscribers = [];
_this.ws = ws;
_this.init();
return _this;
}
TeonetCli.prototype.init = function () {
var _this = this;
var authserver = new TeonetAuth(this);
// When connected to websocket
this.onopen = function (ev) {
console.debug("TeonetCli::teocli.onopen");
// Prepare client name
_this.status = Teonet.status.logining;
if (!_this.client_name) {
// Get name from local storage
var user = authserver.storage.get();
console.debug("TeonetCli::init user", user);
if (user.remember_me && user.accessToken) {
_this.setClientName(user.accessToken);
}
else {
_this.setClientName('teoclits-' + Math.floor((Math.random() * 100) + 1));
}
}
// Send login command to teonet L0 server
_this.login(_this.client_name);
// Set reconnect timeout (reconnect if does not login during timeout
setTimeout(function () {
if (!_this.isInit()) {
console.debug("TeonetCli::teocli.onopen can't login - disconnect");
_this.disconnect();
}
}, _this.INIT_TIMEOUT);
};
// When disconnect from web socket (reconnect)
// Send 'teonet-close' to subscribers
this.onclose = function (ev) {
console.debug("TeonetCli::teocli.onclose");
// Reconnect after timeout
setTimeout(function () {
delete _this.ws;
_this.status = Teonet.status.connecting;
_this.ws = new WebSocket(_this.connect_url);
_this.ws.onopen = _this.onopen;
_this.ws.onclose = _this.onclose;
_this.ws.onerror = _this.onerror;
_this.ws.onmessage = function (ev) {
if (!_this.process(ev.data)) {
//if (typeof this.onmessage === 'function') {
// this.onmessage(ev);
//}
}
};
}, _this.RECONNECT_TIMEOUT);
_this.sendEvent(TeonetCli.EVENT.TEONET_CLOSE);
_this.status = Teonet.status.offline;
_this.inited = false;
};
// When get websocket error
this.onerror = function (ev) { };
// When get 'onother' message fom webspcket. Check cmd 96 - teo-auth answer
// Send 'teonet-init' to subscribers
// Send 'onother' to subscribers
this.onother = function (err, data) {
console.debug("TeonetCli::onother", err, data);
var processed = 0;
var d = data;
// Check login answer
if (d && d.cmd === 96) {
console.debug("TeonetCli:: Got check login answer", d);
// Set name
_this.setClientName(d.data.name);
// Get user from storage
var user = authserver.storage.get();
// Send teocli-init event
var sendEventInit_1 = function (loggedin) {
if (loggedin === void 0) { loggedin = false; }
_this.sendEvent(TeonetCli.EVENT.TEONET_INIT);
_this.status = Teonet.status.online;
_this.inited = true;
if (loggedin)
_this.sendEvent(TeonetCli.EVENT.TEONET_LOGGEDIN);
//$rootScope.networksItems = data.data.networks;
};
// Login success
if (_this.getClientName() == user.userId + ':' + user.clientId) {
sendEventInit_1(true);
}
else {
// Login with saved email and password if remember_me is set
if (user.remember_me) {
//authserver.refresh(); // refresh auth token
authserver.login(user.email, authserver.base64.decode(user.password), function (err, response) {
if (err) {
// Goto Login screen
sendEventInit_1();
_this.loginPage();
}
else {
// Reconect with new client name
_this.setClientName(authserver.getUser().accessToken);
_this.disconnect();
}
});
}
else {
sendEventInit_1();
_this.loginPage();
}
}
processed = 1;
}
if (!processed)
_this.sendEvent('onother', data);
return processed;
};
// Send 'onecho' to subscribers
this.onecho = function (err, data) {
console.debug("TeonetCli::onecho", err, data);
_this.sendEvent('onecho', data);
return 1;
};
// Send 'onclients' to subscribers
this.onclients = function (err, data) {
console.debug("TeonetCli::onclients", err, data);
_this.sendEvent('onclients', data);
return 1;
};
// Send 'onpeers' to subscribers
this.onpeers = function (err, data) {
console.debug("TeonetCli::onpeers", err, data);
_this.sendEvent('onpeers', data);
return 1;
};
};
/**
* Disconnect TeonetCli
*
*/
TeonetCli.prototype.disconnect = function () {
this.ws.close();
};
TeonetCli.prototype.getConnectUrl = function () {
return this.connect_url.replace('ws://', '').replace('/ws', '');
};
TeonetCli.prototype.setConnectUrl = function (url) {
this.connect_url = 'ws://' + url + '/ws';
};
/**
* Sel login page
*/
TeonetCli.prototype.setLoginPage = function (func) {
this.login_page = func;
};
/**
* Load Login page
*/
TeonetCli.prototype.loginPage = function (push) {
if (push === void 0) { push = undefined; }
if (this.login_page)
this.login_page(push);
else {
alert('TODO: Login page is udefined!');
}
};
/**
* Sel SignUp page
*/
TeonetCli.prototype.setSignupPage = function (func) {
this.signup_page = func;
};
/**
* Load SignUp page
*/
TeonetCli.prototype.signupPage = function (push) {
if (push === void 0) { push = undefined; }
if (this.signup_page)
this.signup_page(push);
else {
alert('TODO: SignUp page is udefined!');
}
};
/**
* Sel Restore page
*/
TeonetCli.prototype.setRestorePage = function (func) {
this.restore_page = func;
};
/**
* Load Restore page
*/
TeonetCli.prototype.restorePage = function (push) {
if (push === void 0) { push = undefined; }
if (this.restore_page)
this.restore_page(push);
else {
alert('TODO: Restore page is udefined!');
}
};
/**
* Is TeonetCli connected and initialized
*
* @returns {boolean} True if connected and initialized
*/
TeonetCli.prototype.isInit = function () {
return this.inited;
};
/**
* Get teonet status
*
* @return {number} Teonet status
*/
TeonetCli.prototype.getStatus = function () {
return this.status;
};
/**
* Get client name
*
* @return {string} Teonet client name
*/
TeonetCli.prototype.getClientName = function () {
return this.client_name;
};
/**
* Set client name
*
* @return {string} Teonet client name
*/
TeonetCli.prototype.setClientName = function (name) {
if (name === void 0) { name = ''; }
this.client_name = name;
};
/**
* Subscribe to even
*
* @param {eventSubscribersFunc} func
*/
TeonetCli.prototype.subscribe = function (func) {
this.eventSubscribers.push(func);
return func;
};
/**
* Unsubscribe from event
*
* @param {eventSubscribersFunc} func
*/
TeonetCli.prototype.unsubscribe = function (func) {
this.eventSubscribers = this.eventSubscribers.filter(function (f) { return f !== func; });
};
/**
* Send event to Event Subscribers
*
* @param {string} ev Event name
* @param {object[]) ...obj Objects send to subscribers
*/
TeonetCli.prototype.sendEvent = function (ev) {
var obj = [];
for (var _i = 1; _i < arguments.length; _i++) {
obj[_i - 1] = arguments[_i];
}
for (var _a = 0, _b = this.eventSubscribers; _a < _b.length; _a++) {
var func = _b[_a];
func(ev, obj);
}
_super.prototype.sendEvent.call(this, ev, obj); // Send event to parrent class
};
TeonetCli.prototype.whenEvent = function (event, func) {
return this.subscribe(function (ev) {
var obj = [];
for (var _i = 1; _i < arguments.length; _i++) {
obj[_i - 1] = arguments[_i];
}
if (ev == event) {
func(obj);
}
return 0;
});
};
TeonetCli.prototype.whenInit = function (func) {
if (this.isInit())
func();
return this.whenEvent(TeonetCli.EVENT.TEONET_INIT, function () {
func();
return 0;
});
};
TeonetCli.prototype.whenClose = function (func) {
return this.whenEvent(TeonetCli.EVENT.TEONET_CLOSE, function () {
func();
return 0;
});
};
TeonetCli.prototype.isTeonetClientsActive = function () {
return this.isTeonetClientsActiveFunc();
};
TeonetCli.prototype.setTeonetClientsActive = function (func) {
this.isTeonetClientsActiveFunc = func;
};
TeonetCli.EVENT = {
TEONET_INIT: 'teonet-init',
TEONET_CLOSE: 'teonet-close',
TEONET_LOGGEDIN: 'teonet-loggedin'
};
TeonetCli.decorators = [
{ type: Injectable },
];
/** @nocollapse */
TeonetCli.ctorParameters = function () { return []; };
return TeonetCli;
}(TeocliRTC));
export { TeonetCli };
;
import { Component } from '@angular/core';
import { IntervalObservable } from 'rxjs/observable/IntervalObservable';
import { TeonetClientsNum } from './teocli.clients';
var TeonetStatus = /** @class */ (function () {
/**
* Constructor connect to Teonet and load TeonetClientsNum class
*/
function TeonetStatus(t) {
this.t = t;
this.peer = ''; //! Peer name Component input
this.label = 'Teo is'; //! Label of state Component input
this.reconnect = 'true'; //! Reconnect when peer don't answer
this.show_peer = 'false'; //! Show peer name Component input
this.time = (this.t.status == Teonet.status.online) ? 0 : -1; //! Peer answer time in ms
this.last_answere = 0.00; //! Last peer answer time
this.SEND_ECHO_AFTER = 1.00; //! Send echo after timeout
this.SET_LOGOFF_AFTER = 3.00; //! Set status logoff after timeout
this.RECONNECT_AFTER = 8.00; //! Reconnect after timeout
console.debug('TeonetStatus::constructor, peer = ' + this.peer);
this.tcli = new TeonetClientsNum(t);
}
/**
* This function calls by angular after html content init
*/
TeonetStatus.prototype.ngAfterContentInit = function () {
var _this = this;
console.debug('TeonetStatus::ngAfterContentInit, peer = ' + this.peer +
', reconnect: ' + this.reconnect);
if (this.peer) {
//Send ping to peer
this.sendEcho();
IntervalObservable.create(1000).subscribe(function () {
if (_this.t.isInit()) {
var date = new Date();
var current = date.valueOf() / 1000.0;
if ((current - _this.last_answere) > _this.SEND_ECHO_AFTER) {
_this.sendEcho();
}
if (!_this.last_answere)
_this.last_answere = current;
if (_this.time >= 0 && _this.last_answere &&
(current - _this.last_answere) > _this.SET_LOGOFF_AFTER) {
console.debug('TeonetStatus::IntervalObservable - set "peer logoff"');
_this.time = -1;
}
if (_this.last_answere &&
(current - _this.last_answere) > _this.RECONNECT_AFTER &&
_this.reconnect == 'true') {
console.debug('TeonetStatus::IntervalObservable' +
'- disconnect from teonet, ' +
'(current - this.last_answere) = ', (current - _this.last_answere));
_this.last_answere = 0;
_this.t.disconnect();
}
}
else
_this.time = -1;
});
// Process echo answer
this.t.whenEvent('onecho', function (data) {
var d = data[0][0];
console.debug('TeonetStatus::onecho', data, d, 'this.peer:', _this.peer);
if (d.from == _this.peer) {
var date = new Date();
_this.time = d.data.time;
_this.last_answere = date.valueOf() / 1000.0;
console.debug('TeonetStatus::onecho this.last_answere:', _this.last_answere);
}
return 0;
});
}
};
/**
* Send ping to peer
*/
TeonetStatus.prototype.sendEcho = function () {
console.debug('TeonetStatus::sendEcho to peer: ' + this.peer);
this.t.echo(this.peer, 'TeonetStatus');
};
/**
* Return true if Teonet is online
* @return {boolean}
*/
TeonetStatus.prototype.ifOnline = function () {
return this.t.status == Teonet.status.online;
};
/**
* Return true if peer input is set
*
* @param {string} peer Peer name
*/
TeonetStatus.prototype.ifPeer = function (peer) {
if (peer)
return true;
else
return false;
};
/**
* Get Teonet status color
*
* @param {number} Teonet status
* @return Teonet status color string
*/
TeonetStatus.prototype.getStatusColor = function (status) {
var color;
switch (status) {
case Teonet.status.offline:
color = 'danger';
break;
case Teonet.status.connecting:
color = 'dark';
break;
case Teonet.status.logining:
color = 'primary';
break;
case Teonet.status.online:
color = 'secondary';
break;
default:
color = 'light';
}
return color;
};
/**
* Get name of Teonet status
*
* @param {number} Teonet status
* @return Teonet status string
*/
TeonetStatus.prototype.getStatusText = function (status) {
var text;
switch (status) {
case Teonet.status.offline:
text = 'Offline';
break;
case Teonet.status.connecting:
text = 'Connecting...';
break;
case Teonet.status.logining:
text = 'Logining';
break;
case Teonet.status.online:
text = 'online';
break;
default:
text = '';
}
return text;
};
TeonetStatus.decorators = [
{ type: Component, args: [{
selector: 'teonet-status',
inputs: ['peer', 'label', 'show_peer', 'reconnect'],
styles: ['\n\
.teonet-status { \n\
opacity: 0.85;\n\
position: relative;\n\
float: right;\n\
right: 20px;\n\
top: 10px;\n\
/*font-size: 60%;*/\n\
}\n\
/deep/ ion-nav.menu-content-open + teonet-status {\n\
display: none;\n\
}\n\
/deep/ ion-app.platform-ios .teonet-status {\n\
top: 22px;\n\
}\n\
.teonet-status-no-badge {\n\
top: 3px;\n\
}\n\
/deep/ ion-app.platform-ios .teonet-status-no-badge {\n\
top: 35px;\n\
}\n\
/deep/ ion-app.platform-android .teonet-status-no-badge {\n\
top: 20px;\n\
}\n\
.teonet-status-badge {\n\
position: absolute;\n\
bottom: -15px;\n\
right: 0;\n\
font-size: 70%;\n\
}\n\
.teonet-badge {\n\
padding: 3px 8px;\n\
text-align: center;\n\
display: inline-block;\n\
min-width: 10px;\n\
/* font-size: 1.3rem; */\n\
font-weight: bold;\n\
line-height: 1;\n\
white-space: nowrap;\n\
vertical-align: baseline;\n\
}\n\
'],
template: '\n\
<span class="teonet-status \n\
text-md-{{ getStatusColor(t.status) }}\n\
{{ (!ifPeer(peer) ? \' teonet-status-no-badge\' : \'\') }}">\n\
{{\n\
(ifOnline() ? label + " " : "") + \n\
getStatusText(t.status) + \n\
(ifOnline() && tcli.num_clients ? ": " + tcli.num_clients : "")\n\
}}\n\
<div *ngIf="ifPeer(peer)"\n\
class="teonet-badge teonet-status-badge badge-md\n\
badge-md-{{ time >= 0 ? \'secondary\' : \'danger\'}}"\n\
>\n\
{{\n\
(peer && show_peer == "true" ? (peer | titlecase) + ": " : "") + \n\
(time >= 0 ? time + " ms" : "offline")\n\
}}\n\
</div>\n\
</span>'
},] },
];
/** @nocollapse */
TeonetStatus.ctorParameters = function () { return [
{ type: TeonetCli }
]; };
return TeonetStatus;
}());
export { TeonetStatus };
//# sourceMappingURL=teocli.module.js.map