From d1e96e09438b4a5c7580b86c469e817a61be991f Mon Sep 17 00:00:00 2001 From: Shulhan Date: Sun, 15 Sep 2024 14:32:48 +0700 Subject: all: commit all generate JavaScript files This is to simplify development on third party where they can clone and include the file directly without installing or running anything to build the files. --- websocket_client.js | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 websocket_client.js (limited to 'websocket_client.js') diff --git a/websocket_client.js b/websocket_client.js new file mode 100644 index 0000000..3cfd1c7 --- /dev/null +++ b/websocket_client.js @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: 2021 M. Shulhan +// SPDX-License-Identifier: GPL-3.0-or-later +const AUTO_RECONNECT_INTERVAL = 5000; +export class WuiWebSocketClient { + constructor(opts) { + this.opts = opts; + this.requestQueue = []; + this.reconnect_id = 0; + this.isOpen = false; + this.error = ""; + this.address = opts.address; + if (opts.auto_reconnect) { + if (opts.auto_reconnect_interval <= 0) { + opts.auto_reconnect_interval = AUTO_RECONNECT_INTERVAL; + } + } + this.connect(); + } + // + // Send the request and wait for response similar to HTTP + // request-response. + // + async Send(req) { + return new Promise((resolve) => { + const wuiRes = { + code: 0, + message: "", + }; + const reqQueue = { + req: req, + cbSuccess: (res) => { + wuiRes.code = res.code; + wuiRes.message = res.message; + if (res.code === 200 && res.body.length > 0) { + wuiRes.data = JSON.parse(atob(res.body)); + } + resolve(wuiRes); + }, + cbFail: (err) => { + wuiRes.code = 500; + wuiRes.message = err; + resolve(wuiRes); + }, + }; + this.requestQueue.push(reqQueue); + this.conn.send(JSON.stringify(req)); + }); + } + connect() { + this.conn = new WebSocket(this.address); + this.conn.onclose = () => { + this.onClose(); + }; + this.conn.onerror = () => { + this.onError(); + }; + this.conn.onmessage = (ev) => { + this.onMessage(ev); + }; + this.conn.onopen = () => { + this.onOpen(); + }; + } + // onClose handle connection closed by cleaning up the request + // queue. + onClose() { + this.requestQueue.forEach((reqq) => { + reqq.cbFail("connection closed"); + }); + this.isOpen = false; + this.error = "connection is closed by server"; + if (this.opts.auto_reconnect && !this.reconnect_id) { + this.reconnect_id = setInterval(() => { + this.connect(); + }, this.opts.auto_reconnect_interval); + } + if (this.opts.onDisconnected) { + this.opts.onDisconnected(); + } + } + onError() { + if (this.opts.onError) { + this.opts.onError(); + } + } + onMessage(ev) { + const res = JSON.parse(ev.data); + this.requestQueue.forEach((reqq, x) => { + if (reqq.req.id === res.id) { + reqq.cbSuccess(res); + this.requestQueue.splice(x, 1); + return; + } + }); + if (this.opts.onBroadcast && res.id == 0) { + this.opts.onBroadcast(res); + } + } + onOpen() { + this.isOpen = true; + this.error = ""; + if (this.reconnect_id) { + clearInterval(this.reconnect_id); + this.reconnect_id = 0; + } + if (this.opts.onConnected) { + this.opts.onConnected(); + } + } +} -- cgit v1.3