import { SubscribeMessage, WebSocketGateway, WebSocketServer, OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect, } from '@nestjs/websockets'; import { Logger, UsePipes } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Server, Socket } from 'socket.io'; import { Repository } from 'typeorm'; import { NotificationEntity } from './notification.entity'; import { GameEntity } from '../game/game.entity'; import { NotificationdDTO } from './notification.dto'; import { ValidationPipe } from '../shared/validation.pipe'; /* NotificationGateway contains websocket server and listener for game-info */ @WebSocketGateway() export class NotificationGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { constructor( //create references to tables as repositories @InjectRepository(NotificationEntity) private notificationRepository: Repository<NotificationEntity>, @InjectRepository(GameEntity) private gameRepository: Repository<GameEntity>, ) {} @WebSocketServer() server: Server; // for debugging: starting server, accepting connection, terminating connection private logger: Logger = new Logger('NotificationGateway'); afterInit(server: Server) { this.logger.log('Server has started'); } handleConnection(client: Socket, ...args: any[]) { this.logger.log(`Client ${client.id} connected`); } handleDisconnect(client: Socket) { this.logger.log(`Client ${client.id} disconnected`); } // notifications for when game needs to be paused / stopped @SubscribeMessage('game-info') @UsePipes(new ValidationPipe()) async handleMessage(client: Socket, data: NotificationdDTO) { // check if the game exists and is either started or paused const game = await this.gameRepository.findOne({ id: data.game }); if (!game) { // inform user about error this.server.to(client.id).emit(data.game, { type: 'error', message: 'Game was not found', }); } if (['STARTED', 'PAUSED'].includes(game.state)) { // send the message to all clients listening to gameId branch this.server.emit(data.game, data); // create entry for notification in db const message = await this.notificationRepository.create(data); await this.notificationRepository.insert(message); } else { // inform user about error this.server.to(client.id).emit(data.game, { type: 'error', message: 'Notifications can be sent only in STARTED and PAUSED state', }); } } }