101 lines
2.8 KiB
JavaScript
101 lines
2.8 KiB
JavaScript
import logger from "./logger.js";
|
|
import { getItem } from "./storage.js";
|
|
|
|
export const ConnectionEvent = {
|
|
Open: 0,
|
|
Closed: 1,
|
|
Ready: 2,
|
|
};
|
|
|
|
export default {
|
|
ws: null,
|
|
log: logger(["Connection"], ["log"]).log,
|
|
messageLog: logger(["Connection", "Message"], ["log"]).log,
|
|
url: getItem("server:gatewayBase"),
|
|
isReady: false,
|
|
reconnectTimeout: 0,
|
|
handlers: new Map(),
|
|
|
|
formatAuthString(password) {
|
|
return `%auth%${btoa(password)}`;
|
|
},
|
|
|
|
connect(password=getItem("auth:token")) {
|
|
this.ws = new WebSocket(this.url);
|
|
this.ws.onerror = (e) => this.log("Error", e);
|
|
this.ws.onopen = () => {
|
|
this.log("Open");
|
|
this.dispatch(ConnectionEvent.Open, 1);
|
|
this.reconnectTimeout = 0;
|
|
this.log("Sending authentication packet");
|
|
this.ws.send(`0${this.formatAuthString(password)}`); // send auth packet
|
|
};
|
|
this.ws.onmessage = ({ data }) => {
|
|
if (data === "1") {
|
|
this.isReady = true;
|
|
this.dispatch(ConnectionEvent.Ready, 1);
|
|
this.log("Handshake complete");
|
|
}
|
|
};
|
|
this.ws.onclose = ({ code }) => {
|
|
this.dispatch(ConnectionEvent.Closed, code);
|
|
|
|
if (code === 4001) {// code for bad auth
|
|
this.log("Closed due to bad auth - skipping reconnect");
|
|
return;
|
|
}
|
|
this.isReady = false;
|
|
this.reconnectTimeout += 400;
|
|
if (this.reconnectTimeout >= 30000)
|
|
this.reconnectTimeout = 30000;
|
|
this.log(`Closed - will reconnect in ${this.reconnectTimeout}ms`);
|
|
setTimeout(() => this.connect(password), this.reconnectTimeout);
|
|
}
|
|
},
|
|
|
|
sendMessage(code, params=[]) {
|
|
let message = code;
|
|
for (let i = 0; i < params.length; i++) {
|
|
const param = params[i];
|
|
if (i == params.length - 1)
|
|
message += param;
|
|
else
|
|
message += param + ";";
|
|
}
|
|
|
|
this.ws.send(message);
|
|
},
|
|
|
|
disconnect() {
|
|
this.ws.close();
|
|
},
|
|
|
|
dispatch(event, data) {
|
|
const eventHandlers = this.handlers.get(event);
|
|
if (!eventHandlers)
|
|
return;
|
|
|
|
eventHandlers.forEach(e => e(data));
|
|
},
|
|
|
|
subscribe(event, handler) {
|
|
if (!this.handlers.get(event)) {
|
|
this.handlers.set(event, new Set());
|
|
}
|
|
|
|
this.handlers.get(event).add(handler);
|
|
return handler; // can later be used for unsubscribe()
|
|
},
|
|
|
|
unsubscribe(event, handler) {
|
|
const eventHandlers = this.handlers.get(event);
|
|
if (!eventHandlers)
|
|
return;
|
|
|
|
eventHandlers.delete(handler);
|
|
|
|
if (eventHandlers.size < 1) {
|
|
this.handlers.delete(event);
|
|
}
|
|
},
|
|
};
|