All files / lib/gateway diagnostics.gateway.ts

72% Statements 18/25
37.5% Branches 3/8
77.77% Functions 7/9
70.83% Lines 17/24

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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101                                    2x         2x       2x               1x             3x 3x 3x 1x 1x           3x 3x                 3x         2x       1x       2x                                   2x 1x            
import {
  OnGatewayConnection,
  OnGatewayDisconnect,
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
  WsResponse,
} from '@nestjs/websockets';
import { Subscription, tap, timer } from 'rxjs';
import { Server, WebSocket } from 'ws';
 
import { dianosticEventsGatewayPort, IUserCountEvent, TDiagData } from '../interfaces/diagnostics.interface';
import { AppDiagnosticsService } from '../services/diagnostics.service';
 
@WebSocketGateway(dianosticEventsGatewayPort, {
  path: '/api/events',
  transports: ['websocket'],
})
export class AppDiagnosticsGateway implements OnGatewayConnection, OnGatewayDisconnect {
  /**
   * Platform-specific server instance.
   */
  @WebSocketServer()
  protected server?: Server;
 
  private dynamicDataSub?: Subscription;
 
  constructor(private readonly service: AppDiagnosticsService) {}
 
  /**
   * Sends an event to a client.
   * @param client web socket client
   * @param data stringified event data
   */
  public sendEvent(client: WebSocket, data: string) {
    client.send(data);
  }
 
  /**
   * Broadcasts an event to all connected users.
   */
  public broadcastEvent<T = Record<string, unknown>>(event: T): void {
    Eif (typeof this.server !== 'undefined') {
      const clients = this.server.clients.values();
      for (const client of clients) {
        const stringifiedEvent = JSON.stringify(event);
        this.sendEvent(client, stringifiedEvent);
      }
    }
  }
 
  private sendClientChangeEvent(): void {
    Eif (typeof this.server !== 'undefined') {
      const event: IUserCountEvent = {
        event: 'users',
        data: [
          {
            name: 'active',
            value: this.server.clients.size,
          },
        ],
      };
      this.broadcastEvent(event);
    }
  }
 
  public async handleConnection() {
    this.sendClientChangeEvent();
  }
 
  public async handleDisconnect() {
    this.sendClientChangeEvent();
  }
 
  @SubscribeMessage('start-diag')
  public startSendingDiagnosticEvents() {
    if (typeof this.dynamicDataSub === 'undefined') {
      const timeout = 5000;
      this.dynamicDataSub = timer(0, timeout)
        .pipe(
          tap(() => {
            const event: WsResponse<TDiagData> = {
              event: 'dynamic',
              data: this.service.dynamic(),
            };
            this.broadcastEvent(event);
          }),
        )
        .subscribe();
    }
  }
 
  @SubscribeMessage('stop-diag')
  public stopSendingDiagnosticEvents() {
    Iif (typeof this.dynamicDataSub !== 'undefined') {
      this.dynamicDataSub.unsubscribe();
      this.dynamicDataSub = void 0;
    }
  }
}