Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
notifications.gateway.ts 2.52 KiB
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',
      });
    }
  }
}