/* * HTTP tunnel over WebRTC - P2P class * Author: Konstantinos Drakontidis * Email: gedra100sh@gmail.com */ import { v4 } from "uuid"; import { WebSocket } from "ws"; import config from "../config/config" export class P2P { private server_instance: WebSocket | null; private clients: Map; public constructor() { this.server_instance = null; this.clients = new Map(); } // Sets the server websocket instance setServer(server_instance: WebSocket): void { this.server_instance = server_instance; } // Gets the server websocket instance getServer(): WebSocket | null { return this.server_instance; } // Adds a client websocket instance to the map addClient(client: WebSocket): string { const id = v4(); this.clients.set(id, { instance: client, timeout: null }); return id; } // Returns client peer instance getPeer(id: string, client: WebSocket): WebSocket | null { if (client == this.server_instance) { const client_instance = this.clients.get(id)?.instance; return (client_instance != undefined) ? client_instance : null; } else { return this.server_instance; } } // Removes client entry from map removeClient(id: string) { return this.clients.delete(id); } // Returns client id getId(client: WebSocket): string | null { var key = null; this.clients.forEach((v, k) => { if (v.instance == client) { key = k; return; } }); return key; } // Clears the P2P instance clear() { this.clients.forEach((v) => { v.instance.close(3001, "Server shutdown."); }) this.server_instance = null; this.clients.clear(); } // Sets client timeout after register setClientTimeout(id: string, p2p: P2P, ws_client: WebSocket, callback: (id: string, p2p: P2P, ws_client: WebSocket) => void) { const instance = this.clients.get(id); if (instance) { this.clients.set(id, { ...instance, timeout: setTimeout(() => { callback(id, p2p, ws_client) }, config.timeout) }); } } // Clears client timeout clearClientTimeout(id: string) { const timeout = this.clients.get(id)?.timeout; if (timeout && (timeout != null)) { clearTimeout(timeout); } } // Returns the total entries in the map getMapSize(): number { return this.clients.size; } };