quad-ws/js/quad-ws.js

120 lines
3.2 KiB
JavaScript
Raw Permalink Normal View History

2023-10-01 23:48:52 +02:00
"use strict";
/**
* Represents a WebSocket connection and its state.
* @typedef {Object} WebSocketConnection
* @property {WebSocket} socket - The WebSocket instance.
* @property {number} state - The state of the WebSocket connection. Possible values:
* - 0: Connection is in the CONNECTING state.
* - 1: Connection is in the OPEN state.
* - 2: Connection is in the CLOSING state.
* - 3: Connection is in the CLOSED state.
* @property {Array} received - An array to store received data or messages.
*/
/**
* An instance of WebSocketConnection.
* @type {{[key: number]: WebSocketConnection}}
*/
let ws = {};
let i = 0;
const WS_NOT_EXISTING = -1;
2023-10-02 00:24:13 +02:00
const WS_DISCONNECTED = 0;
const WS_CONNECTED = 1;
2023-10-01 23:48:52 +02:00
const WS_CLOSED = 2;
2023-10-02 14:09:07 +02:00
function ws_open_js(url, id) {
2023-10-01 23:48:52 +02:00
let conn;
try {
conn = {
socket: new WebSocket(url),
2023-10-02 14:09:07 +02:00
url,
state: WS_CONNECTED,
2023-10-01 23:48:52 +02:00
received: []
};
} catch (error) {
return -1;
}
2023-10-02 00:24:13 +02:00
2023-10-01 23:48:52 +02:00
conn.socket.onopen = (s, e) => {
2023-10-02 00:24:13 +02:00
conn.state = WS_CONNECTED;
2023-10-01 23:48:52 +02:00
};
2023-10-02 00:47:16 +02:00
conn.socket.onmessage = (e) => {
2023-10-06 14:41:37 +02:00
e.data.arrayBuffer().then((d) => {
conn.received.push(new Uint8Array(d));
});
2023-10-01 23:48:52 +02:00
};
conn.socket.onerror = (s, e) => {
2023-10-02 14:09:07 +02:00
conn.state = WS_DISCONNECTED;
2023-10-01 23:48:52 +02:00
};
conn.socket.onclose = (s, e) => {
2023-10-02 14:09:07 +02:00
conn.state = WS_DISCONNECTED;
//delete ws[id];
//ws[id] = undefined;
2023-10-01 23:48:52 +02:00
};
ws[id] = conn;
return id;
}
2023-10-02 14:09:07 +02:00
function ws_open(ptr, len) {
let url = UTF8ToString(ptr, len);
return ws_open_js(url, i++);
}
function ws_revive(id) {
if (ws[id] == null) return false;
if (ws[id].state == WS_NOT_EXISTING || ws[id].state == WS_CLOSED) return false;
if (ws[id].state == WS_CONNECTED) return true;
return ws_open_js(ws[id].url, id) == id;
}
2023-10-01 23:48:52 +02:00
function ws_write(id, ptr, len) {
let data = new Uint8Array(wasm_memory.buffer, ptr, len);
/*let data = new Uint8Array(len);
for (let i = 0; i < len; i++) {
data[i] = data_in[i];
}*/
2023-10-02 00:24:13 +02:00
if (ws[id] != null && ws[id].socket.readyState == WebSocket.OPEN) {
2023-10-01 23:48:52 +02:00
ws[id].socket.send(data);
return true;
}
return false;
}
function ws_available(id) {
2023-10-02 14:09:07 +02:00
if (ws[id] == null || ws[id].received == null || ws[id].received.length == 0) return -1;
2023-10-01 23:48:52 +02:00
return ws[id].received[0].length;
}
function ws_read(id, ptr, max_length) {
let file = ws[id].received.pop();
var dest = new Uint8Array(wasm_memory.buffer, ptr, max_length);
for (let i = 0; i < file.length && i < max_length; i++) {
dest[i] = file[i];
}
}
function ws_state(id) {
return ws[id]?.state ?? WS_NOT_EXISTING;
}
function ws_close(id) {
if (ws[id] == null) return;
ws[id].socket.close();
ws[id].state = WS_CLOSED;
2023-10-02 14:09:07 +02:00
ws[id] = { state: WS_CLOSED };
2023-10-01 23:48:52 +02:00
}
function register_plugin(importObject) {
importObject.env.ws_open = ws_open;
2023-10-02 14:09:07 +02:00
importObject.env.ws_revive = ws_revive;
2023-10-01 23:48:52 +02:00
importObject.env.ws_write = ws_write;
importObject.env.ws_read = ws_read;
importObject.env.ws_available = ws_available;
importObject.env.ws_state = ws_state;
importObject.env.ws_close = ws_close;
}
miniquad_add_plugin({ register_plugin, version: "0.0.1", name: "miniquad_websocket" });