| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- /**
- * Lego 09 — Surveillance Gateway
- * Lego 11 — Socket Event Schema: monitor:subscribe / monitor:data
- *
- * Registers the Socket.io namespace on port 3000 (shared server).
- * On client subscribe → sends the latest snapshot immediately.
- * Every 500ms tick → SurveillanceService calls back → we broadcast to all.
- */
- import {
- WebSocketGateway,
- WebSocketServer,
- SubscribeMessage,
- OnGatewayInit,
- OnGatewayConnection,
- OnGatewayDisconnect,
- } from '@nestjs/websockets';
- import { Logger, OnModuleInit } from '@nestjs/common';
- import { Server, Socket } from 'socket.io';
- import { SurveillanceService, MonitorPayload, MonitorStatus } from './surveillance.service';
- @WebSocketGateway({
- cors: { origin: '*' }, // Angular dev server on any port
- namespace: '/monitor',
- })
- export class SurveillanceGateway
- implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect, OnModuleInit
- {
- @WebSocketServer()
- private server!: Server;
- private readonly logger = new Logger(SurveillanceGateway.name);
- constructor(private readonly surveillanceService: SurveillanceService) {}
- // ─── Lifecycle ─────────────────────────────────────────────────────────────
- onModuleInit() {
- // Wire the service callback → broadcasts to all connected clients
- this.surveillanceService.registerMetricsCallback((metrics: MonitorPayload[]) => {
- this.broadcast(metrics);
- });
- // Wire webhook probe results → broadcast monitor:status to all clients
- this.surveillanceService.registerStatusCallback((status: MonitorStatus) => {
- if (this.server) this.server.emit('monitor:status', status);
- });
- }
- afterInit(server: Server) {
- this.logger.log('🔌 SurveillanceGateway initialized on /monitor namespace');
- }
- handleConnection(client: Socket) {
- this.logger.log(`📡 Client connected: ${client.id}`);
- // Immediately push the current snapshot so the UI isn't blank on load
- const snapshot = this.surveillanceService.getLatestMetrics();
- if (snapshot.length > 0) {
- client.emit('monitor:data', snapshot);
- }
- // Push the latest webhook status immediately so the UI doesn't wait 10 s
- client.emit('monitor:status', this.surveillanceService.getLatestStatus());
- }
- handleDisconnect(client: Socket) {
- this.logger.log(`🔌 Client disconnected: ${client.id}`);
- }
- // ─── Event Handlers ────────────────────────────────────────────────────────
- /**
- * Lego 11 — monitor:subscribe
- * UI emits this to start (or re-confirm) the resource tracking stream.
- * We acknowledge and immediately push the latest snapshot.
- */
- @SubscribeMessage('monitor:subscribe')
- handleSubscribe(client: Socket) {
- this.logger.log(`🟢 monitor:subscribe from ${client.id}`);
- const snapshot = this.surveillanceService.getLatestMetrics();
- client.emit('monitor:data', snapshot);
- return { event: 'monitor:subscribed', data: { ok: true } };
- }
- // ─── Broadcast ─────────────────────────────────────────────────────────────
- private broadcast(metrics: MonitorPayload[]) {
- if (this.server) {
- this.server.emit('monitor:data', metrics);
- }
- }
- }
|