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 | 7x 7x 7x 7x 7x 7x 35x 7x 35x 35x 35x 19x 19x 19x 19x 19x 19x 19x 19x 3x 3x 4x 3x 3x 3x 3x 3x 3x 13x 13x 11x 2x 2x 8x 4x 4x 4x 1x 2x 24x 3x 7x 1x | import { MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse } from '@nestjs/websockets'; import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { map } from 'rxjs/operators'; import { Server, WebSocket } from 'ws'; import { IncomingMessage } from 'http'; import { Logger } from '@nestjs/common'; import { BroadcastingEvent } from './interfaces'; @WebSocketGateway({ path: '/ws' }) export class WebsocketGateway implements OnGatewayConnection, OnGatewayDisconnect { private readonly logger = new Logger(WebsocketGateway.name); @WebSocketServer() private server!: Server; // magically injected private clients: { [token: string] : WebSocket } = {}; private clientsCount$: BehaviorSubject<number> = new BehaviorSubject<number>(0); private clientLost$: Subject<string> = new Subject<string>(); handleConnection(client: WebSocket, message: IncomingMessage): void { const token = WebsocketGateway.getTokenFromUrl(message.url as string); this.clients[token] = client; this.clientsCount$.next(Object.values(this.clients).length); this.logger.log(`client connected: ${token}`); } static getTokenFromUrl(url: string): string { const urlSearchParams = new URL(`xx://dumm.y/${url}`).searchParams; const token = urlSearchParams.get('token'); Iif (!token) { throw new Error('No token!'); } return token; } handleDisconnect(client: WebSocket): void { let disconnectedToken = ''; Object.keys(this.clients).forEach((token: string) => { if (this.clients[token] === client) { delete this.clients[token]; disconnectedToken = token; } }); if (disconnectedToken !== '') { this.clientLost$.next(disconnectedToken); this.clientsCount$.next(Object.values(this.clients).length); this.logger.log(`client disconnected: ${disconnectedToken}`); } } broadcastToRegistered(tokens: string[], event: BroadcastingEvent, message: any): void { const payload = JSON.stringify({ event, data: message }); tokens.forEach((token: string) => { if (typeof this.clients[token] !== 'undefined') { this.logger.log(`sending to client: ${token}`); this.clients[token].send(payload); } }); } disconnectClient(monitorToken: string): void { if (typeof this.clients[monitorToken] !== 'undefined') { this.logger.log(`disconnect client: ${monitorToken}`); this.clients[monitorToken].close(); delete this.clients[monitorToken]; } } disconnectAll(): void { Object.keys(this.clients).forEach((token: string) => { this.disconnectClient(token); }); } getDisconnectionObservable(): Observable<string> { return this.clientLost$.asObservable(); } getClientTokens(): string[] { return Object.keys(this.clients); } @SubscribeMessage('subscribe:client.count') subscribeClientCount(@MessageBody() data: number): Observable<WsResponse<number>> { return this.clientsCount$.pipe(map((count: number) => ({ event: 'client.count', data: count }))); } } |