You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.1 KiB
JavaScript
92 lines
2.1 KiB
JavaScript
class WebSocketConnection extends Connection {
|
|
static priority = 800;
|
|
static name = 'WS';
|
|
|
|
#ws;
|
|
#packet_buffer;
|
|
#reconnect;
|
|
|
|
onConnChange(s){}
|
|
|
|
constructor(hub) {
|
|
super(hub);
|
|
this.options.enabled = false;
|
|
this.options.ip = false;
|
|
this.options.port = false;
|
|
this.options.connect_timeout = 3000;
|
|
|
|
this.#packet_buffer = new PacketBufferScanFirst(data => {
|
|
this.hub._parsePacket(this, data);
|
|
});
|
|
}
|
|
|
|
isConnected() {
|
|
return this.#ws && this.#ws.readyState == 1;
|
|
}
|
|
|
|
async begin(){}
|
|
async discover(){}
|
|
async search(){}
|
|
|
|
async connect() {
|
|
if (this.#ws) return;
|
|
|
|
this._setState(ConnectionState.CONNECTING);
|
|
this.#reconnect = true;
|
|
this.#ws = await WebSocketConnection.#wsOpenAsync(`ws://${this.options.ip}:${this.options.port}/`, ['hub'], this.options.connect_timeout);
|
|
|
|
this._setState(ConnectionState.CONNECTED);
|
|
this.#packet_buffer.clear();
|
|
|
|
this.#ws.onclose = async () => {
|
|
this._setState(ConnectionState.DISCONNECTED);
|
|
this.#ws = undefined;
|
|
await sleep(500);
|
|
if (this.#reconnect)
|
|
await this.connect();
|
|
};
|
|
|
|
this.#ws.onmessage = (e) => {
|
|
this.#packet_buffer.push(e.data);
|
|
};
|
|
}
|
|
|
|
async disconnect() {
|
|
this._setState(ConnectionState.DISCONNECTED);
|
|
this.#reconnect = false;
|
|
if (this.isConnected())
|
|
this.#ws.close();
|
|
}
|
|
|
|
async send(text) {
|
|
if (this.isConnected())
|
|
this.#ws.send(text);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {string} url
|
|
* @param {string[]} protos
|
|
* @param {number} timeout
|
|
* @returns {Promise<WebSocket>}
|
|
*/
|
|
static #wsOpenAsync(url, protos, timeout) {
|
|
return new Promise((res, rej) => {
|
|
const tid = setTimeout(handler, timeout);
|
|
|
|
function handler(e) {
|
|
ws.removeEventListener('open', handler);
|
|
ws.removeEventListener('error', handler);
|
|
clearTimeout(tid);
|
|
|
|
if (ws.readyState === WebSocket.OPEN)
|
|
res(ws);
|
|
else rej(e ?? new TimeoutError());
|
|
}
|
|
|
|
const ws = new WebSocket(url, protos);
|
|
ws.addEventListener('open', handler);
|
|
ws.addEventListener('error', handler);
|
|
})
|
|
}
|
|
} |