UNPKG

ws-event-emitter

Version:

Provides a event emitter linked between clients and server using web socket (includes permission handeling)

159 lines 5.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WSConnection = void 0; const events_1 = require("events"); const WSHandler_1 = require("./WSHandler"); class WSConnection extends events_1.EventEmitter { constructor(ws, req) { super({ captureRejections: true }); this.ws = null; this.conPara = null; this.closed = false; this.closedClean = false; this.localEmitters = []; this.autoReconnectTimeout = null; // WS is passed as function (autoReconnect: on) if (typeof ws == "function") this.reconnect(ws); // WS is passed as function (autoReconnect: off) else { this.ws = ws; this.ws.on("close", this.close.bind(this)); this.ws.on("message", this.onRawMessage.bind(this)); } this.req = req; } reconnect(func) { var reconnectHandler = () => { if (this.closedClean) return; console.warn("[WSConnection] WS lost connection, reconnecting in 5s..."); this.closed = true; this.emit("close_reconnect"); this.autoReconnectTimeout = setTimeout(() => { this.reconnect(func); }, 5000); }; try { this.ws = func() .on("open", () => { this.closed = false; if (this.ws) this.ws.on("error", (err) => this.emit("error", err, this.ws)); }) .on("close", reconnectHandler) .on("message", this.onRawMessage.bind(this)); } catch (err) { reconnectHandler(); } } /** Returns a new Event Emitter that is bound to this Connection */ createLocalEmitter() { return this.bindLocalEmitter(new events_1.EventEmitter({ captureRejections: true })); } /** * Binds a existing Event Emitter to this Connection\ * !!! Will modify the emit method of the emitter !!! */ bindLocalEmitter(eventEmitter) { if (typeof eventEmitter._WSHandler_originalEmit == "object") throw new Error("Emitter is bound. Cannot bind again"); var emit = eventEmitter.emit.bind(eventEmitter); eventEmitter._WSHandler_originalEmit = emit; eventEmitter.emit = (eventName, ...args) => { this.send({ type: "event", event: eventName, args: args, }); return true; }; this.localEmitters.push(eventEmitter); return eventEmitter; } unbindLocalEmitter(eventEmitter) { if (typeof eventEmitter._WSHandler_originalEmit != "object") throw new Error("Emitter is not bound. Cannot unbind"); eventEmitter.emit = eventEmitter._WSHandler_originalEmit; eventEmitter._WSHandler_originalEmit = undefined; this.localEmitters = this.localEmitters.filter((e) => e != eventEmitter); return eventEmitter; } /** Internal ws.message handler */ onRawMessage(raw, isBinary) { if (isBinary) return; // TODO: Send ERROR var data = null; try { data = JSON.parse(raw); } catch (err) { return; // TODO: Send ERROR } finally { if (data === null) return; // TODO: Send ERROR if (typeof data != "object") return; // TODO: Send ERROR if (Array.isArray(data)) return; // TODO: Send ERROR if (typeof data.type != "string") return; // TODO: Send ERROR this.onParsedMessage(data); } } /** Internal message handler */ onParsedMessage(message) { switch (message.type) { case "event": if (typeof message.event != "string") return; if (typeof message.args != "object") return; if (!Array.isArray(message.args)) return; var event = message; this.emit("event", event); this.localEmitters.forEach(e => e._WSHandler_originalEmit(event.event, ...event.args)); break; case "error": if (typeof message.code != "number") return; if (typeof message.message != "string") return; this.emit("error", new WSHandler_1.StatusError(message.code, message.message)); break; default: this.emit("error", new Error("Unknown message type: " + message.type)); break; } } /** Send a WSEventMessage to this connection */ send(message) { if (!this.closed && this.ws) this.ws.send(JSON.stringify(message)); else { console.error("Event was lost due to web scoket being closed."); } } /** Close this connection */ close() { this.closed = true; this.closedClean = true; if (this.ws) this.ws.close(); this.emit("close"); this.ws = null; } /** Set Custom Parameters (Can be any)*/ setParameter(para) { this.conPara = para; } /** Get Custom Parameters (Can be any)*/ getParameter() { return this.conPara; } } exports.WSConnection = WSConnection; //# sourceMappingURL=WSConnection.js.map