databag/app/sdk/src/connection.ts
2024-10-04 14:49:00 -07:00

116 lines
3.1 KiB
TypeScript

import { EventEmitter } from "eventemitter3";
import { Logging } from "./api";
import { Revision } from "./entities";
import { Call } from "./types";
export class Connection {
private log: Logging;
private closed: boolean;
private emitter: EventEmitter;
private websocket: WebSocket;
constructor(log: Logging, token: string, node: string, secure: boolean) {
this.closed = false;
this.log = log;
this.emitter = new EventEmitter();
this.websocket = this.setWebSocket(token, node, secure);
}
public async close() {
this.closed = true;
if (this.websocket) {
this.websocket.close();
}
}
public addRevisionListener(ev: (revision: Revision) => void): void {
this.emitter.on("revision", ev);
}
public removeRevisionListener(ev: (revision: Revision) => void): void {
this.emitter.off("revision", ev);
}
public addRingListener(ev: (call: Call) => void): void {
this.emitter.on("call", ev);
}
public removeRingListener(ev: (call: Call) => void): void {
this.emitter.off("call", ev);
}
public addStatusListener(ev: (status: string) => void): void {
this.emitter.on("status", ev);
}
public removeStatusListener(ev: (status: string) => void): void {
this.emitter.off("status", ev);
}
private setWebSocket(token: string, node: string, secure: boolean): WebSocket {
if (this.closed) {
this.emitter.emit("status", "closed");
return this.websocket;
}
this.emitter.emit("status", "connecting");
const wsUrl = `ws${secure ? "s" : ""}://${node}/status?mode=ring`;
const ws = new WebSocket(wsUrl);
ws.onmessage = (e) => {
try {
if (e.data === "") {
this.close();
}
const activity = JSON.parse(e.data);
this.emitter.emit("status", "connected");
if (activity.revision) {
this.emitter.emit("revision", activity.revision as Revision);
} else if (activity.ring) {
const { cardId, callId, calleeToken, ice, iceUrl, iceUsername, icePassword } = activity.ring;
const call: Call = {
cardId,
callId,
calleeToken,
ice: ice
? ice
: [
{
urls: iceUrl,
username: iceUsername,
credential: icePassword,
},
],
};
this.emitter.emit("call", call);
} else {
this.emitter.emit("revision", activity as Revision);
}
} catch (err) {
console.log(err);
ws.close();
}
};
ws.onclose = (e) => {
console.log(e);
this.emitter.emit("status", "disconnected");
setTimeout(() => {
if (ws != null) {
ws.onmessage = () => {};
ws.onclose = () => {};
ws.onopen = () => {};
ws.onerror = () => {};
this.websocket = this.setWebSocket(token, node, secure);
}
}, 1000);
};
ws.onopen = () => {
ws.send(JSON.stringify({ AppToken: token }));
};
ws.onerror = (e) => {
console.log(e);
ws.close();
};
return ws;
}
}