| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- /**
- * Lego 09 / Lego 11 — Surveillance HUD Service
- *
- * Opens a persistent Socket.io connection to NestJS /monitor namespace.
- * Emits monitor:subscribe on connect and keeps the tunnel alive indefinitely.
- * Exposes signals for the PerformanceHUD and chatbot status indicators.
- *
- * Exposes nestStatus (ONLINE/OFFLINE) derived from socket connection state.
- */
- import { Injectable, signal, computed, OnDestroy } from '@angular/core';
- import { io, Socket } from 'socket.io-client';
- import { environment } from '../../environments/environment';
- export interface MonitorPayload {
- service: string;
- pid: number;
- cpu: number;
- memory: number; // bytes
- timestamp: string;
- }
- @Injectable({ providedIn: 'root' })
- export class SurveillanceService implements OnDestroy {
- /** Live metrics — HUD reads this signal directly */
- readonly metrics = signal<MonitorPayload[]>([]);
- readonly connected = signal<boolean>(false);
- /** Derived status string — consumed by Scanner and HUD */
- readonly nestStatus = computed<'ONLINE' | 'OFFLINE'>(() =>
- this.connected() ? 'ONLINE' : 'OFFLINE'
- );
- private socket: Socket;
- constructor() {
- // Persistent tunnel — opened on service construction (app boot)
- this.socket = io(`${environment.nestWsUrl}/monitor`, {
- transports: ['websocket'],
- reconnection: true,
- reconnectionDelay: 1000,
- secure: true,
- rejectUnauthorized: false,
- });
- this.socket.on('connect', () => {
- this.connected.set(true);
- this.socket.emit('monitor:subscribe');
- });
- this.socket.on('disconnect', () => {
- this.connected.set(false);
- });
- this.socket.on('monitor:data', (payload: MonitorPayload[]) => {
- this.metrics.set(payload);
- });
- }
- ngOnDestroy() {
- this.socket.disconnect();
- }
- formatBytes(bytes: number): string {
- if (bytes === 0) return '0 B';
- const mb = bytes / (1024 * 1024);
- return `${mb.toFixed(1)} MB`;
- }
- }
|