@hms-networks/kolibri-js-client
Version:
Kolibri Consumer API client for building kolibri based applications
145 lines • 6.65 kB
JavaScript
"use strict";
/*
* Copyright 2021 HMS Industrial Networks AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http: //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.KolibriConnection = void 0;
const kolibri_js_core_1 = require("@hms-networks/kolibri-js-core");
const websocket_as_promised_1 = __importDefault(require("websocket-as-promised"));
const class_transformer_1 = require("class-transformer");
const websocket_1 = require("websocket");
class KolibriConnection {
constructor(options) {
var _a, _b;
this.options = options;
this.reconnectRetries = 0;
this.reconnectBackoffTime = 1;
this.clientMessageListener = options.clientMessageListener;
this.reconnectRetries = (_b = (_a = this.options.reconnectOptions) === null || _a === void 0 ? void 0 : _a.maxReconnects) !== null && _b !== void 0 ? _b : 0;
}
addClientMessageListener(listener) {
this.clientMessageListener = listener;
}
addOnReconnectListener(listener) {
this.onReconnectListener = listener;
}
addOnDisconnectListener(listener) {
this.onDisconnectListener = listener;
}
async sendRequest(request) {
const plainRequest = (0, class_transformer_1.classToPlain)(request);
const requestId = request.id;
if (!(0, kolibri_js_core_1.isDefined)(this.socket) || !this.socket.isOpened) {
throw new Error('Socket is not open!');
}
return this.socket.sendRequest(plainRequest, { requestId: requestId });
}
async sendResponse(response) {
const plainResponse = (0, class_transformer_1.classToPlain)(response);
if (!(0, kolibri_js_core_1.isDefined)(this.socket) || !this.socket.isOpened) {
throw new Error('Socket is not open!');
}
return this.socket.sendPacked(plainResponse);
}
async connect() {
this.socket = this.createWebSocket(this.options.url.toString(), this.options.protocol);
this.addListeners();
try {
await this.socket.open();
}
catch (e) {
throw new Error('Could not open connection!');
}
}
async close() {
var _a;
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();
}
disableReconnect() {
var _a;
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.onClose.mute();
}
enableReconnect() {
var _a;
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.onClose.unmute();
}
createWebSocket(brokerUrl, kolibriProtocol) {
return new websocket_as_promised_1.default(brokerUrl, {
createWebSocket: url => {
var _a;
return new websocket_1.w3cwebsocket(url, kolibriProtocol, undefined, undefined, this.options.requestOptions, { tlsOptions: (_a = this.options.tlsOptions) !== null && _a !== void 0 ? _a : {} });
},
packMessage: data => JSON.stringify(data),
unpackMessage: data => JSON.parse(data),
attachRequestId: (data, requestId) => Object.assign({ id: requestId }, data),
extractRequestId: data => data && data.id
});
}
addListeners() {
var _a, _b, _c, _d;
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.onUnpackedMessage.addListener((msg) => { var _a; (_a = this.clientMessageListener) === null || _a === void 0 ? void 0 : _a.call(this, msg); });
if (this.options.reconnectOptions) {
(_b = this.socket) === null || _b === void 0 ? void 0 : _b.onClose.addOnceListener(async (event) => {
var _a;
await ((_a = this.onDisconnectListener) === null || _a === void 0 ? void 0 : _a.call(this, { code: event.code, reason: event.reason }));
});
(_c = this.socket) === null || _c === void 0 ? void 0 : _c.onClose.addListener(async () => { await this.reconnectHandler(); });
}
else {
(_d = this.socket) === null || _d === void 0 ? void 0 : _d.onClose.addListener(async (event) => {
var _a;
await ((_a = this.onDisconnectListener) === null || _a === void 0 ? void 0 : _a.call(this, { code: event.code, reason: event.reason }));
});
}
}
async reconnectHandler() {
if (this.reconnectRetries > 0) {
setTimeout(async () => {
var _a, _b;
try {
await ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.open());
// successfully connected
this.resetReconnectConfig();
await ((_b = this.onReconnectListener) === null || _b === void 0 ? void 0 : _b.call(this));
}
catch (e) {
this.prepareReconnectConfigForNextTry();
}
}, this.reconnectBackoffTime * 1000);
}
else {
// Do nothing - Could not reconnect. Giving up
}
}
resetReconnectConfig() {
var _a, _b, _c;
this.reconnectBackoffTime = 1;
this.reconnectRetries = (_b = (_a = this.options.reconnectOptions) === null || _a === void 0 ? void 0 : _a.maxReconnects) !== null && _b !== void 0 ? _b : 0;
(_c = this.socket) === null || _c === void 0 ? void 0 : _c.onClose.addOnceListener(async (event) => {
var _a;
await ((_a = this.onDisconnectListener) === null || _a === void 0 ? void 0 : _a.call(this, { code: event.code, reason: event.reason }));
});
}
prepareReconnectConfigForNextTry() {
var _a, _b;
this.reconnectRetries--;
this.reconnectBackoffTime = Math.min(this.reconnectBackoffTime * 2, (_b = (_a = this.options.reconnectOptions) === null || _a === void 0 ? void 0 : _a.maxReconnectDelay) !== null && _b !== void 0 ? _b : 1);
}
}
exports.KolibriConnection = KolibriConnection;
//# sourceMappingURL=kolibri_connection.js.map