All files / src/Instance/IO Wss.ts

88.23% Statements 15/17
50% Branches 1/2
75% Functions 6/8
88.23% Lines 15/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76                                                  3x 3x 3x             1x 1x   1x                     1x 1x             1x 1x 1x 1x   1x 1x     1x                    
/**
 *
 * @module WebSockets
 * @category IO
 * @internal
 */
 
import WebSocket, { WebSocketServer } from "ws";
import { WebSocketConnection } from "./Wss/Connection";
import crypto from "node:crypto";
import { IncomingMessage } from "http";
import { Socket } from "net";
 
/**
 * Class for handling WebSockets connections
 * Keeps track of and delegates the WebSocket connection
 * Also provides methods for retrieving and closing connections
 */
export class WebSockets {
  private readonly server: WebSocketServer;
  private connections: Map<string, WebSocketConnection>;
  /**
   * Constructor for WebSockets class
   */
  constructor() {
    this.connections = new Map<string, WebSocketConnection>();
    this.server = new WebSocketServer({ noServer: true });
    this.server.on("connection", this.handleConnection.bind(this));
  }
  /**
   * Method that handles incoming connections
   * @param ws - The WebSocket instance
   */
  private handleConnection(ws: WebSocket) {
    let connection = new WebSocketConnection(ws);
    let newConnectionID = this.setID(connection);
 
    ws.on("close", () => {
      this.connections.delete(newConnectionID);
    });
  }
  /**
   * Handle WebSocket upgrade
   * @param request - IncomingMessage object representing the request to the server
   * @param socket - Socket object representing the underlying connection
   * @param head - Buffer holding the first packet of the upgraded stream
   */
  public handleUpgrade(request: IncomingMessage, socket: Socket, head: Buffer) {
    this.server.handleUpgrade(request, socket, head, (ws) => {
      this.server.emit("connection", ws, request);
    });
  }
  /**
   * Method that creates a new ID for a connection
   */
  private setID(connection: WebSocketConnection): string {
    let newID = "";
    do {
      let id = `WSID:${crypto.randomBytes(20).toString("hex")}`;
      newID = !this.connections.has(id) ? id : "";
    } while (newID === "");
    this.connections.set(newID, connection);
    return newID;
  }
  public async stop() {
    this.server.close();
  }
  /**
   * Asynchronous method that indicates if the WebSockets server is ready
   * @returns A promise that resolves to a boolean indicating if the server is ready
   */
  async isReady(): Promise<boolean> {
    return true;
  }
}