lavva.exalushome
Version:
Library implementing communication and abstraction layers for ExalusHome system
587 lines • 34 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import * as signalR from "@microsoft/signalr";
import { DataFrame, Method, Status } from "../DataFrame";
import { ConnectionResult, AuthorizationInfo, ConnectionState, StreamError } from "./IExalusConnectionService";
import { TypedEvent } from "../TypedEvent";
import { Api } from '../Api';
import { LoggerService } from "./Logging/LoggerService";
import { Event } from "../Event";
import { ControllerConfigurationService } from "./Controller/ControllerConfigurationService";
import { WebApiCacheService } from './WebApi/WebApiCacheService';
import { SessionService } from "./Session/SessionService";
export class ExalusConnectionService {
constructor() {
this._logPackets = false;
this._pingInterval = 5000;
this._disconnectedOnPurpose = false;
this._defaultPacketsBrokerAddress = "packets-broker1.tr7.pl";
this._serversBrokerAddress = "https://servers-broker.tr7.pl";
this._serversBrokerAddressList = ["https://servers-broker.tr7.pl", "https://broker.tr7.pl"];
this._allBrokersChecked = false;
this._address = "packets-broker1.tr7.pl";
this._isEstabilished = false;
this._timeout = 10000;
this._dataReceivedEvent = new TypedEvent();
this._pongReceivedEvent = new Event();
this._authorizationReceivedEvent = new TypedEvent();
this._registrationReceivedEvent = new TypedEvent();
this._streamStartedEvent = new TypedEvent();
this._connectionStateChangedEvent = new TypedEvent();
this._errorOccuredEvent = new TypedEvent();
this._log = Api.Get(LoggerService.ServiceName);
this._controllerConfiguration = null;
this._cache = null;
this._session = null;
this._packetsBrokerServers = ["packets-broker1.tr7.pl", "br1.tr7.pl", "br1.exala.pl"];
this._lastReceivedPacketTime = Date.now();
this._connectedAtLeastOnce = false;
this._pingIntervalId = null;
}
SubscribeTo(resourceId, handler) {
let sub = (frame) => {
if (frame.Resource === resourceId)
handler(frame);
};
this.OnDataReceivedEvent().Subscribe(sub);
return () => this.OnDataReceivedEvent().Unsubscribe(sub);
}
GetControllerSerialNumber() {
return this._serialId;
}
GetControllerPin() {
return this._PIN;
}
GetServiceName() {
return ExalusConnectionService.ServiceName;
}
EnablePacketsLogging() {
this._logPackets = true;
}
DisablePacketsLogging() {
this._logPackets = false;
}
InitializeConnection() {
this._controllerConfiguration = Api.Get(ControllerConfigurationService.ServiceName);
this._cache = Api.Get(WebApiCacheService.ServiceName);
this._session = Api.Get(SessionService.ServiceName);
if (this._connection) {
try {
this._connection.stop();
}
catch (ex) { }
this._connection = undefined;
}
if (!this._address)
throw new Error("Domain is not set");
if (!this._serialId)
throw new Error("SerialId is not set");
if (!this._PIN)
throw new Error("PIN is not set");
this._connection = new signalR.HubConnectionBuilder()
.configureLogging(signalR.LogLevel.Debug)
.withUrl(`https://${this._address}/broker`, {
skipNegotiation: true,
transport: signalR.HttpTransportType.WebSockets
})
.build();
this._dataReceivedEvent.Subscribe((frame) => {
this._lastReceivedPacketTime = Date.now();
});
this._pingIntervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
yield this.PingControllerAsync();
}), this._pingInterval);
}
GetAuthorizationInfo() {
if (this._serialId != null && this._PIN != null)
return new AuthorizationInfo(this._serialId, this._PIN);
else
return null;
}
SetServersBrokerAddress(address) {
this._serversBrokerAddress = address;
}
SetDefaultPacketsBrokerAddress(address) {
this._defaultPacketsBrokerAddress = address;
this._address = address;
}
GetServerAddressAsync() {
return __awaiter(this, void 0, void 0, function* () {
try {
let result = yield fetch(`${this._serversBrokerAddress}/api/connections/broker/whichserver/${this._serialId}`);
//OK
if (result.status === 200) {
let address = yield result.text();
if (!address) {
this._log.Error(ExalusConnectionService.ServiceName, `Failed to get server address, status: ${result.status}`);
return null;
}
this._log.Debug(ExalusConnectionService.ServiceName, `Got server address: ${address}`);
return address;
}
//Break reccurency
else if (this._allBrokersChecked) {
this._allBrokersChecked = false;
return null;
}
//No content
else if (result.status === 204) {
this.swapBrokersAsync(false);
return this.GetServerAddressAsync();
}
else {
this._log.Error(ExalusConnectionService.ServiceName, `Failed to get server address, status: ${result.status}`);
return null;
}
}
catch (ex) {
this._log.Error(ExalusConnectionService.ServiceName, ex);
return null;
}
});
}
ConnectAsync(address) {
return __awaiter(this, void 0, void 0, function* () {
this._connectedAtLeastOnce = false;
this._address = address;
return yield this.connectAsync();
});
}
AuthorizeAsync(authorizationInfo) {
let timeoutTime = 2000;
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
var _a;
let timeoutId = 0;
let sub = (result) => {
window.clearTimeout(timeoutId);
this._log.Debug(ExalusConnectionService.ServiceName, `Got authorization result: ${result}`);
this._connectedAtLeastOnce = true;
resolve(result);
};
let onTimeout = () => {
window.clearTimeout(timeoutId);
this._authorizationReceivedEvent.Unsubscribe(sub);
resolve(false);
};
timeoutId = window.setTimeout(onTimeout, timeoutTime);
this._log.Debug(ExalusConnectionService.ServiceName, `Authorizing to cloud using: ${authorizationInfo.SerialNumber} PIN: ${authorizationInfo.PIN}`);
this._authorizationReceivedEvent.Subscribe(sub);
yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.send("AuthorizeTo", authorizationInfo.SerialNumber, authorizationInfo.PIN));
}));
}
ConnectAndAuthorizeAsync(authorizationInfo) {
return __awaiter(this, void 0, void 0, function* () {
this._connectedAtLeastOnce = false;
Api.WorksInContextOf = authorizationInfo.SerialNumber;
this._serialId = authorizationInfo.SerialNumber;
this._PIN = authorizationInfo.PIN;
var packetsBroker = yield this.GetServerAddressAsync();
if (!packetsBroker || packetsBroker == null || packetsBroker == "") {
let result = ConnectionResult.ControllerIsNotConnected;
this._log.Warning(ExalusConnectionService.ServiceName, `Server did not return packets broker address, trying to connect to known brokers.`);
for (let server of this._packetsBrokerServers) {
this._log.Warning(ExalusConnectionService.ServiceName, `Testing connection to ${server}`);
this.SetDefaultPacketsBrokerAddress(server);
try {
if (this.IsConnected())
yield this.DisconnectAsync();
}
catch (ex) { }
this._log.Warning(ExalusConnectionService.ServiceName, `Connecting to server: ${server}`);
let conResult = yield this.connectAsync();
this._log.Warning(ExalusConnectionService.ServiceName, `Connection result: ${conResult}`);
if (conResult == ConnectionResult.Connected)
if (yield this.AuthorizeAsync(authorizationInfo)) {
result = ConnectionResult.Connected;
this._connectedAtLeastOnce = true;
return result;
}
else {
this._log.Warning(ExalusConnectionService.ServiceName, `Failed to authorize in ${server}`);
}
}
return result;
}
else {
this._log.Debug(ExalusConnectionService.ServiceName, `Got packets broker address: ${packetsBroker}`);
this.SetDefaultPacketsBrokerAddress(packetsBroker);
let conResult = yield this.connectAsync();
if (conResult != ConnectionResult.Connected)
return conResult;
var authResult = yield this.AuthorizeAsync(authorizationInfo);
if (!authResult) {
this._connectedAtLeastOnce = false;
yield this.swapBrokersAsync();
if (!this._allBrokersChecked)
return this.ConnectAndAuthorizeAsync(authorizationInfo);
else
this._allBrokersChecked = false;
}
if (authResult)
this._connectedAtLeastOnce = true;
return authResult ? ConnectionResult.Connected : ConnectionResult.AuthorizationFailed;
}
});
}
swapBrokersAsync() {
return __awaiter(this, arguments, void 0, function* (disconnect = true) {
if (disconnect)
yield this.DisconnectAsync();
var intexOfLastBroker = this._serversBrokerAddressList.lastIndexOf(this._serversBrokerAddress);
if (intexOfLastBroker + 1 < this._serversBrokerAddressList.length) {
this._serversBrokerAddress = this._serversBrokerAddressList[intexOfLastBroker + 1];
this._log.Debug(`Changing address of next broker from: ${this._serversBrokerAddressList[intexOfLastBroker]} to: ${this._serversBrokerAddressList[intexOfLastBroker + 1]}`);
}
else {
this._log.Debug(`All brokers checked, changing address to first one: ${this._serversBrokerAddressList[0]}`);
this._allBrokersChecked = true;
this._serversBrokerAddress = this._serversBrokerAddressList[0];
}
});
}
connectAsync() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
let result = ConnectionResult.FailedToConnect;
if (!this._address)
return Promise.resolve(ConnectionResult.ControllerIsNotConnected);
if (this._disconnectedOnPurpose) {
this._disconnectedOnPurpose = false;
}
const connectionEvent = this._connectionStateChangedEvent;
this.InitializeConnection();
(_a = this._connection) === null || _a === void 0 ? void 0 : _a.onclose(() => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
if (!this._disconnectedOnPurpose)
this._log.Error(ExalusConnectionService.ServiceName, `Connection closed`);
else
this._log.Info(ExalusConnectionService.ServiceName, `Connection closed on demand.`);
Api.Get(SessionService.ServiceName).CreateSessionCompletionSourceAsync();
this.FireConnectionStateChanged();
if (((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) !== signalR.HubConnectionState.Disconnected)
return;
if (this._disconnectedOnPurpose)
return;
yield ((_b = this._connection) === null || _b === void 0 ? void 0 : _b.start());
if (this._connection != null) {
if (yield this.AuthorizeAsync(new AuthorizationInfo(this._serialId, this._PIN))) {
this._log.Info(ExalusConnectionService.ServiceName, `Reconnected from onClose`);
return this.FireConnectionStateChanged();
}
}
return ConnectionResult.FailedToConnect;
}));
(_b = this._connection) === null || _b === void 0 ? void 0 : _b.onreconnected(() => __awaiter(this, void 0, void 0, function* () {
if (yield this.AuthorizeAsync(new AuthorizationInfo(this._serialId, this._PIN))) {
this._log.Info(ExalusConnectionService.ServiceName, `Reconnected from onreconnected`);
return this.FireConnectionStateChanged();
}
}));
(_c = this._connection) === null || _c === void 0 ? void 0 : _c.onreconnecting(() => {
this._log.Warning(ExalusConnectionService.ServiceName, `Reconnecting...`);
return this.FireConnectionStateChanged();
});
yield ((_d = this._connection) === null || _d === void 0 ? void 0 : _d.start());
(_e = this._connection) === null || _e === void 0 ? void 0 : _e.on("Pong", () => {
this._log.Debug(ExalusConnectionService.ServiceName, "Pong received <-");
this._pongReceivedEvent.Invoke();
});
(_f = this._connection) === null || _f === void 0 ? void 0 : _f.on("Registration", (data) => {
var _a;
(_a = this._registrationReceivedEvent) === null || _a === void 0 ? void 0 : _a.Invoke(data);
});
(_g = this._connection) === null || _g === void 0 ? void 0 : _g.on("Authorization", (data) => {
var _a;
(_a = this._authorizationReceivedEvent) === null || _a === void 0 ? void 0 : _a.Invoke(data);
});
(_h = this._connection) === null || _h === void 0 ? void 0 : _h.on("SendError", (sender, data) => __awaiter(this, void 0, void 0, function* () {
if (sender.startsWith("NotAuthorized:")) {
this._log.Error(ExalusConnectionService.ServiceName, "Failed to authorize!");
yield this.AuthorizeAsync(new AuthorizationInfo(this._serialId, this._PIN));
}
else {
this._log.Error(ExalusConnectionService.ServiceName, `Server returned error: ${sender} ${data}`);
this._errorOccuredEvent.Invoke([sender, data]);
}
}));
(_j = this._connection) === null || _j === void 0 ? void 0 : _j.on("ControllerDisconnected", (data) => __awaiter(this, void 0, void 0, function* () {
if (this._serialId === data) {
this._log.Warning(ExalusConnectionService.ServiceName, `Controller disconnected: ${data}`);
yield this.DisconnectAsync();
}
}));
(_k = this._connection) === null || _k === void 0 ? void 0 : _k.on("StreamStarted", (streamTransactionId) => {
var _a;
(_a = this._streamStartedEvent) === null || _a === void 0 ? void 0 : _a.Invoke(streamTransactionId);
});
let dataReceivedEvent = this._dataReceivedEvent;
(_l = this._connection) === null || _l === void 0 ? void 0 : _l.on("Data", (sender, data) => {
const d = JSON.parse(data);
if (this._logPackets || window["packets"] === true)
this._log.Debug(ExalusConnectionService.ServiceName, `Received data:\n${JSON.stringify(d, null, 2)}`);
dataReceivedEvent.Invoke(d);
});
if (this._connection != null)
return this.FireConnectionStateChanged();
return ConnectionResult.FailedToConnect;
});
}
FireConnectionStateChanged() {
var _a;
const connectionEvent = this._connectionStateChangedEvent;
switch ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) {
case signalR.HubConnectionState.Connected:
connectionEvent.Invoke(ConnectionState.Connected);
return ConnectionResult.Connected;
case signalR.HubConnectionState.Connecting:
connectionEvent.Invoke(ConnectionState.Connecting);
return ConnectionResult.Connected;
case signalR.HubConnectionState.Disconnected:
if (this._connectedAtLeastOnce) {
connectionEvent.Invoke(ConnectionState.Disconnected);
return ConnectionResult.FailedToConnect;
}
break;
case signalR.HubConnectionState.Disconnecting:
if (this._connectedAtLeastOnce) {
connectionEvent.Invoke(ConnectionState.Disconnecting);
return ConnectionResult.FailedToConnect;
}
break;
case signalR.HubConnectionState.Reconnecting:
connectionEvent.Invoke(ConnectionState.Reconnecting);
return ConnectionResult.FailedToConnect;
}
return ConnectionResult.FailedToConnect;
}
DisconnectAsync() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
this._disconnectedOnPurpose = true;
this._log.Debug(ExalusConnectionService.ServiceName, `Disconnecting from the server ${this._address}`);
this._connectionStateChangedEvent.Invoke(ConnectionState.Disconnecting);
if (this._pingIntervalId !== null)
clearInterval(this._pingIntervalId);
yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.stop());
});
}
IsConnected() {
var _a;
return ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) === signalR.HubConnectionState.Connected;
}
SendAndWaitForResponseAsync(dataFrame, timeout, useCache, logTransmission = true) {
return this.SendAndWaitForResponseWithRepeatAsync(dataFrame, timeout, useCache, logTransmission);
}
SendAndWaitForResponseWithRepeatAsync(dataFrame_1, timeout_1, useCache_1) {
return __awaiter(this, arguments, void 0, function* (dataFrame, timeout, useCache, repeat = true, logTransmission = true) {
var _a, _b, _c;
if (dataFrame.Method === Method.Get && useCache) {
if (!(yield ((_a = this._controllerConfiguration) === null || _a === void 0 ? void 0 : _a.DidCofigurationChangeAsync()))) {
let res = (_b = this._cache) === null || _b === void 0 ? void 0 : _b.GetCache(dataFrame);
if (res !== null) {
return Promise.resolve(res);
}
}
}
let timeoutId = 0;
const startTime = Date.now();
if (!this.IsConnected())
throw new Error("Connection is not established");
if (dataFrame.Resource !== "/users/user/login")
yield ((_c = this._session) === null || _c === void 0 ? void 0 : _c.WaitForSessionCreationAsync());
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
let onReceivedFrame = (receivedFrame) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
if ((receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId) == dataFrame.TransactionId) {
window.clearTimeout(timeoutId);
this._dataReceivedEvent.Unsubscribe(onReceivedFrame);
const difference = Date.now() - startTime;
if (logTransmission)
this._log.Debug(ExalusConnectionService.ServiceName, `Received response for: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Resource} ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Method} id: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId} in ${difference}ms`);
if (dataFrame.Method === Method.Get && useCache)
(_a = this._cache) === null || _a === void 0 ? void 0 : _a.Cache(receivedFrame);
if (!useCache && (receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status) === Status.UserIsNotLoggedIn && repeat) {
((_b = this._session) === null || _b === void 0 ? void 0 : _b.OnUserLoggedOutEvent()).Invoke((_c = this._session) === null || _c === void 0 ? void 0 : _c.User);
yield ((_d = this._session) === null || _d === void 0 ? void 0 : _d.RestoreSessionAsync());
resolve(yield this.SendAndWaitForResponseWithRepeatAsync(dataFrame, timeout, useCache, false, logTransmission));
}
resolve(receivedFrame);
}
});
this._dataReceivedEvent.Subscribe(onReceivedFrame);
timeoutId = window.setTimeout(() => {
this._dataReceivedEvent.Unsubscribe(onReceivedFrame);
let errorMessage = `Response timeout, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`;
this._log.Error(ExalusConnectionService.ServiceName, errorMessage);
reject(new signalR.TimeoutError(errorMessage));
}, timeout);
if (!(yield this.SendAsync(dataFrame, logTransmission))) {
let errorMessage = `Failed to send request, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`;
reject(new Error(errorMessage));
}
}));
});
}
SendAndHandleResponseAsync(dataFrame_1, timeout_1, dataHandler_1) {
return __awaiter(this, arguments, void 0, function* (dataFrame, timeout, dataHandler, logTransmission = true) {
var _a;
let timeoutId = 0;
const startTime = Date.now();
if (!this.IsConnected())
throw new Error("Connection is not established");
if (dataFrame.Resource !== "/users/user/login")
yield ((_a = this._session) === null || _a === void 0 ? void 0 : _a.WaitForSessionCreationAsync());
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
const enableTimeout = () => window.setTimeout(() => {
this._dataReceivedEvent.Unsubscribe(onReceivedFrame);
let errorMessage = `Response timeout, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`;
this._log.Error(ExalusConnectionService.ServiceName, errorMessage);
reject(new signalR.TimeoutError(errorMessage));
}, timeout);
let onReceivedFrame = (receivedFrame) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
if ((receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId) == dataFrame.TransactionId) {
window.clearTimeout(timeoutId);
const difference = Date.now() - startTime;
if (logTransmission || window["packets"] === true)
this._log.Debug(ExalusConnectionService.ServiceName, `Received response for: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Resource} ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Method} id: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId} in ${difference}ms`);
if ((receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status) === Status.UserIsNotLoggedIn) {
this._dataReceivedEvent.Unsubscribe(onReceivedFrame);
((_a = this._session) === null || _a === void 0 ? void 0 : _a.OnUserLoggedOutEvent()).Invoke((_b = this._session) === null || _b === void 0 ? void 0 : _b.User);
yield ((_c = this._session) === null || _c === void 0 ? void 0 : _c.RestoreSessionAsync());
resolve(yield this.SendAndHandleResponseAsync(dataFrame, timeout, dataHandler, logTransmission));
}
switch (receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status) {
case Status.MultiDataResponseStart:
case Status.MultiDataResponse:
dataHandler(receivedFrame);
timeoutId = enableTimeout();
break;
case Status.MultiDataResponseStop:
case Status.FatalError:
case Status.Error:
dataHandler(receivedFrame);
this._dataReceivedEvent.Unsubscribe(onReceivedFrame);
resolve();
break;
default:
let errorMessage = `Failed to process MultiDataResponse - recived incorrect response status: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}
make sure that the requested endpoint uses MultiDataResponse, otherwise use SendAndWaitForResponseAsync<T> method.`;
reject(new Error(errorMessage));
break;
}
}
});
this._dataReceivedEvent.Subscribe(onReceivedFrame);
timeoutId = enableTimeout();
if (!(yield this.SendAsync(dataFrame, logTransmission))) {
let errorMessage = `Failed to send request, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`;
reject(new Error(errorMessage));
}
}));
});
}
SendAndHandleStreamAsync(dataFrame_1, streamHandler_1) {
return __awaiter(this, arguments, void 0, function* (dataFrame, streamHandler, logTransmission = true) {
var _a;
let timeoutId = 0;
const startTime = Date.now();
if (!this.IsConnected())
throw new Error("Connection is not established");
if (dataFrame.Resource !== "/users/user/login")
yield ((_a = this._session) === null || _a === void 0 ? void 0 : _a.WaitForSessionCreationAsync());
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
const enableTimeout = () => window.setTimeout(() => {
this._streamStartedEvent.Unsubscribe(onStreamStarted);
let errorMessage = `Waiting for stream timeout occurs, stream was not registered in 8000ms, make sure that method supports streaming! Resource: ${dataFrame.Resource} method: ${dataFrame.Method} stream/transaction id: ${dataFrame.TransactionId}`;
this._log.Error(ExalusConnectionService.ServiceName, errorMessage);
reject(new signalR.TimeoutError(errorMessage));
}, 8000);
if (!(yield this.SendAsync(dataFrame, logTransmission))) {
let errorMessage = `Failed to send request, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`;
reject(new Error(errorMessage));
}
let onStreamStarted = (streamTransactionId) => __awaiter(this, void 0, void 0, function* () {
var _a;
if (streamTransactionId == dataFrame.TransactionId) {
window.clearTimeout(timeoutId);
const difference = Date.now() - startTime;
if (logTransmission || window["packets"] === true)
this._log.Debug(ExalusConnectionService.ServiceName, `Received stream registration message for stream ${streamTransactionId} in ${difference}ms`);
(_a = this._connection) === null || _a === void 0 ? void 0 : _a.stream("WatchStream", dataFrame.TransactionId).subscribe({
next: (item) => {
streamHandler.Next(item);
if (logTransmission || window["packets"] === true)
this._log.Debug(ExalusConnectionService.ServiceName, `Received stream packet for stream ${streamTransactionId}`);
},
complete: () => {
streamHandler.Complete();
if (logTransmission || window["packets"] === true)
this._log.Debug(ExalusConnectionService.ServiceName, `Received stream complete message for stream ${streamTransactionId}`);
resolve();
},
error: (err) => {
streamHandler.Error(err);
const errorMessage = `Failed to subscribe for stream: ${dataFrame.TransactionId}, error: ${err}`;
reject(new StreamError(errorMessage));
},
});
}
});
this._streamStartedEvent.Subscribe(onStreamStarted);
timeoutId = enableTimeout();
}));
});
}
PingControllerAsync() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) !== signalR.HubConnectionState.Connected)
return false;
if (this._lastReceivedPacketTime !== null && Date.now() - this._lastReceivedPacketTime < this._pingInterval)
return false;
let frame = new DataFrame();
frame.Resource = "/system/ping";
frame.Method = Method.Get;
let result = yield this.SendAndWaitForResponseAsync(frame, 2000, false, false)
.then(() => true)
.catch(() => false);
return result;
});
}
SendAsync(dataFrame, logTransmission = false) {
if (!this.IsConnected())
throw new Error("Connection is not established");
return new Promise((resolve) => {
var _a;
if (this._logPackets || window["packets"] === true)
this._log.Debug(ExalusConnectionService.ServiceName, `Sent DataFrame ${dataFrame.Resource} ${dataFrame.Method} transaction id: ${dataFrame.TransactionId} data:\n${JSON.stringify(dataFrame, null, 2)}`);
else if (logTransmission)
this._log.Debug(ExalusConnectionService.ServiceName, `Sent DataFrame ${dataFrame.Resource} ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`);
(_a = this._connection) === null || _a === void 0 ? void 0 : _a.invoke("SendTo", this._serialId, dataFrame).then(() => {
resolve(true);
}).catch(err => {
this._log.Error(ExalusConnectionService.ServiceName, `${err}`);
resolve(false);
});
});
}
OnDataReceivedEvent() {
return this._dataReceivedEvent;
}
OnConnectionStateChangedEvent() {
return this._connectionStateChangedEvent;
}
OnErrorOccuredEvent() {
return this._errorOccuredEvent;
}
}
ExalusConnectionService.ServiceName = "ExalusConnectionService";
//# sourceMappingURL=ExalusConnectionService.js.map