@robotical/ricjs
Version:
Javascript/TS library for Robotical RIC
191 lines • 7.26 kB
JavaScript
;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RICJS
// Communications Library
//
// Rob Dobson & Chris Greening 2020-2022
// (C) 2020-2022
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const isomorphic_ws_1 = tslib_1.__importDefault(require("isomorphic-ws"));
const RICLog_1 = tslib_1.__importDefault(require("./RICLog"));
const RICUtils_1 = tslib_1.__importDefault(require("./RICUtils"));
const RICConnEvents_1 = require("./RICConnEvents");
class RICChannelWebSocket {
constructor() {
// Message handler
this._ricMsgHandler = null;
// Websocket we are connected to
this._webSocket = null;
// Last message tx time
// private _msgTxTimeLast = Date.now();
// private _msgTxMinTimeBetweenMs = 15;
// Is connected
this._isConnected = false;
// Conn event fn
this._onConnEvent = null;
// File Handler parameters
this._requestedBatchAckSize = 10;
this._requestedFileBlockSize = 500;
}
fhBatchAckSize() { return this._requestedBatchAckSize; }
fhFileBlockSize() { return this._requestedFileBlockSize; }
// isConnected
isConnected() {
return this._isConnected;
}
// Set message handler
setMsgHandler(ricMsgHandler) {
this._ricMsgHandler = ricMsgHandler;
}
// WebSocket interfaces require subscription to published messages
requiresSubscription() {
return true;
}
// Set onConnEvent handler
setOnConnEvent(connEventFn) {
this._onConnEvent = connEventFn;
}
// Get connected locator
getConnectedLocator() {
return this._webSocket;
}
// Connect to a device
async connect(locator) {
// Debug
RICLog_1.default.debug("RICChannelWebSocket.connect " + locator.toString());
// Connect
const connOk = await this._wsConnect("ws://" + locator + "/ws");
return connOk;
}
// Disconnect
async disconnect() {
var _a;
// Not connected
this._isConnected = false;
// Disconnect websocket
(_a = this._webSocket) === null || _a === void 0 ? void 0 : _a.close(1000);
// Debug
RICLog_1.default.debug(`RICChannelWebSocket.disconnect attempting to close websocket`);
}
pauseConnection(pause) { RICLog_1.default.verbose(`pauseConnection ${pause} - no effect for this channel type`); return; }
// Handle notifications
_onMsgRx(msg) {
// Debug
if (msg !== null) {
RICLog_1.default.verbose(`RICChannelWebSocket._onMsgRx ${RICUtils_1.default.bufferToHex(msg)}`);
}
// Handle message
if (msg !== null && this._ricMsgHandler) {
this._ricMsgHandler.handleNewRxMsg(msg);
}
}
// Send a message
async sendTxMsg(msg, sendWithResponse) {
var _a;
// Check connected
if (!this._isConnected)
return false;
// Debug
RICLog_1.default.verbose(`RICChannelWebSocket.sendTxMsg ${msg.toString()} sendWithResp ${sendWithResponse.toString()}`);
// Send over websocket
try {
await ((_a = this._webSocket) === null || _a === void 0 ? void 0 : _a.send(msg));
}
catch (error) {
RICLog_1.default.warn(`RICChannelWebSocket.sendTxMsg - send failed ${error}`);
return false;
}
return true;
}
async sendTxMsgNoAwait(msg, sendWithResponse) {
var _a;
// Check connected
if (!this._isConnected)
return false;
// Debug
RICLog_1.default.verbose(`RICChannelWebSocket.sendTxMsgNoAwait ${msg.toString()} sendWithResp ${sendWithResponse.toString()}`);
// Send over websocket
(_a = this._webSocket) === null || _a === void 0 ? void 0 : _a.send(msg);
return true;
}
async _wsConnect(locator) {
// Check already connected
if (await this.isConnected()) {
return true;
}
// Form websocket address
const wsURL = locator.toString();
// Connect to websocket
// try {
// this._webSocket = await this._webSocketOpen(wsURL);
// } catch (error: any) {
// RICLog.debug(`Unable to create WebSocket ${error.toString()}`);
// return false;
// }
this._webSocket = null;
return new Promise((resolve, reject) => {
this._webSocketOpen(wsURL).then((ws) => {
this._webSocket = ws;
RICLog_1.default.debug(`_wsConnect - opened connection`);
// Handle messages
this._webSocket.onmessage = (evt) => {
// RICLog.debug("WebSocket rx");
if (evt.data instanceof ArrayBuffer) {
const msg = new Uint8Array(evt.data);
this._onMsgRx(msg);
}
};
// Handle close event
this._webSocket.onclose = (evt) => {
RICLog_1.default.info(`_wsConnect - closed code ${evt.code} wasClean ${evt.wasClean} reason ${evt.reason}`);
this._webSocket = null;
this._isConnected = false;
// Event handler
if (this._onConnEvent) {
this._onConnEvent(RICConnEvents_1.RICConnEvent.CONN_DISCONNECTED_RIC);
}
};
// Resolve the promise - success
resolve(true);
}).catch((err) => {
if (err instanceof Error) {
RICLog_1.default.verbose(`WS open failed ${err.toString()}`);
}
// Resolve - failed
reject(false);
});
});
}
async _webSocketOpen(url) {
return new Promise((resolve, reject) => {
// Debug
// RICLog.debug('Attempting WebSocket connection');
// Open the socket
try {
const webSocket = new isomorphic_ws_1.default(url);
// Open socket
webSocket.binaryType = "arraybuffer";
webSocket.onopen = (_evt) => {
RICLog_1.default.debug(`RICChannelWebSocket._webSocketOpen - onopen ${_evt.toString()}`);
// // We're connected
this._isConnected = true;
resolve(webSocket);
};
webSocket.onerror = function (evt) {
RICLog_1.default.warn(`RICChannelWebSocket._webSocketOpen - onerror: ${evt.message}`);
reject(evt);
};
}
catch (error) {
RICLog_1.default.warn(`RICChannelWebSocket._webSocketOpen - open failed ${error}`);
reject(error);
}
});
}
}
exports.default = RICChannelWebSocket;
//# sourceMappingURL=RICChannelWebSocket.js.map