@cimo/websocket
Version:
Websocket (server/client). Light, fast and secure.
201 lines • 7.56 kB
JavaScript
import * as helperSrc from "../HelperSrc.js";
export default class Manager {
ws;
address;
handleReceiveDataList;
clientIdCurrent;
callbackConnection;
callbackDisconnection;
handleReceiveData = (tag, data) => {
for (let a = 0; a < this.handleReceiveDataList.length; a++) {
const handleReceiveData = this.handleReceiveDataList[a];
if (handleReceiveData.tag === tag) {
handleReceiveData.callback(data);
break;
}
}
};
handleReceiveDataDelete = (tag) => {
for (let a = this.handleReceiveDataList.length - 1; a >= 0; a--) {
if (this.handleReceiveDataList[a].tag === tag) {
this.handleReceiveDataList.splice(a, 1);
}
}
};
create = () => {
this.ws = new WebSocket(this.address);
this.ws.binaryType = "arraybuffer";
this.ws.onopen = () => {
helperSrc.writeLog("@cimo/websocket - Client - Manager.ts - create() - onopen()", "Connection open.");
if (this.callbackConnection) {
this.callbackConnection();
}
};
let messageTagDownload = "";
this.ws.onmessage = (event) => {
if (this.ws) {
if (typeof event.data === "string") {
const eventData = event.data;
if (eventData.trim() === "") {
return;
}
if (!helperSrc.jsonCheck(eventData)) {
return;
}
const eventDataObject = JSON.parse(eventData);
if (!eventDataObject || typeof eventDataObject.tag !== "string") {
return;
}
if (eventDataObject.tag === "cws_clientId_current") {
this.clientIdCurrent = helperSrc.base64ToUtf8(eventDataObject.data);
}
if (eventDataObject.tag === "cws_download") {
messageTagDownload = eventDataObject.tag;
}
this.handleReceiveData(eventDataObject.tag, eventDataObject.data);
}
else if (typeof event.data !== "string" && messageTagDownload) {
const dataView = new DataView(event.data);
this.handleReceiveData(messageTagDownload, dataView);
messageTagDownload = "";
}
}
};
this.ws.onclose = () => {
helperSrc.writeLog("@cimo/websocket - Client - Manager.ts - create() - onclose()", "Connection close.");
this.ws = undefined;
if (this.callbackDisconnection) {
this.callbackDisconnection();
}
};
};
constructor(addressValue) {
this.ws = undefined;
this.address = addressValue;
this.handleReceiveDataList = [];
this.clientIdCurrent = "";
this.callbackConnection = undefined;
this.callbackDisconnection = undefined;
}
checkStatus = (mode, callback) => {
if (mode === "connection") {
this.callbackConnection = callback;
}
else if (mode === "disconnection") {
this.callbackDisconnection = callback;
}
};
sendMessage = (mode, data, tag = "", timeout = 0) => {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
if (!(data instanceof ArrayBuffer) && !(typeof data === "string") && !(typeof data === "object" && data !== null)) {
helperSrc.writeLog("@cimo/websocket - Client - Manager.ts - sendMessage()", "Invalid data type!");
}
if (mode === "text" && !(data instanceof ArrayBuffer)) {
let resultData = "";
if (typeof data === "string") {
resultData = data;
}
else if (typeof data === "object") {
resultData = JSON.stringify(data);
}
const encodedBytes = new TextEncoder().encode(resultData);
let binaryString = "";
for (let a = 0; a < encodedBytes.length; a++) {
binaryString += String.fromCharCode(encodedBytes[a]);
}
const messageObject = {
tag: `cws_${tag}`,
data: window.btoa(binaryString)
};
if (timeout > 0) {
const timeoutEvent = setTimeout(() => {
clearTimeout(timeoutEvent);
if (this.ws) {
this.ws.send(JSON.stringify(messageObject));
}
}, timeout);
}
else {
this.ws.send(JSON.stringify(messageObject));
}
}
else if (mode === "binary" && data instanceof ArrayBuffer) {
this.ws.send(data);
}
else {
helperSrc.writeLog("@cimo/websocket - Client - Manager.ts - sendMessage()", "Message type doesn't match mode!");
}
}
else {
helperSrc.writeLog("@cimo/websocket - Client - Manager.ts - sendMessage()", "Client not connected!");
}
};
sendDataBroadcast = (data) => {
this.sendMessage("text", data, "broadcast");
};
sendDataUpload = (mimeType, fileName, file) => {
this.sendMessage("text", { mimeType, fileName }, "upload");
this.sendMessage("binary", file, "", 100);
};
sendDataDirect = (dataValue, clientId) => {
if (clientId !== "") {
const data = {
time: new Date().toISOString(),
content: dataValue,
fromClientId: this.clientIdCurrent,
toClientId: clientId
};
this.sendMessage("text", data, "direct");
}
};
receiveData = (tag, callbackValue) => {
const cwsTag = `cws_${tag}`;
this.handleReceiveDataDelete(cwsTag);
this.handleReceiveDataList.push({
tag: cwsTag,
callback: (data) => {
let resultData;
if (typeof data === "string") {
const decoded = helperSrc.base64ToUtf8(data);
resultData = !helperSrc.jsonCheck(decoded) ? decoded : JSON.parse(decoded);
}
else {
resultData = data;
}
callbackValue(resultData);
}
});
};
receiveDataDownload = (callback) => {
let mimeType = "";
let fileName = "";
this.receiveData("download", (data) => {
if (data instanceof DataView) {
callback(data, mimeType, fileName);
mimeType = "";
fileName = "";
}
else {
mimeType = data.mimeType;
fileName = data.fileName;
}
});
};
receiveDataDirect = (callback) => {
this.receiveData("direct", (data) => {
callback(data);
});
};
open = () => {
if (!this.ws) {
this.create();
}
};
close = () => {
if (this.ws) {
this.sendMessage("text", "", "disconnect");
this.ws.close();
}
};
}
//# sourceMappingURL=Manager.js.map