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" });
|