diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/controllers/chat_room.controller.ts | 11 | ||||
-rw-r--r-- | server/database/migrations/1648605030863-AddChatRoom.ts | 5 | ||||
-rw-r--r-- | server/database/migrations/1648844808010-AddConnectedUsers.ts | 54 | ||||
-rw-r--r-- | server/entities/chat_room.entity.ts | 9 | ||||
-rw-r--r-- | server/entities/chat_room_connection.entity.ts | 15 | ||||
-rw-r--r-- | server/modules/chat_room.module.ts | 3 | ||||
-rw-r--r-- | server/providers/gateways/chat_room.gateway.ts | 40 | ||||
-rw-r--r-- | server/providers/services/chat_room.service.ts | 44 |
8 files changed, 163 insertions, 18 deletions
diff --git a/server/controllers/chat_room.controller.ts b/server/controllers/chat_room.controller.ts index 3917e54..9b75c1f 100644 --- a/server/controllers/chat_room.controller.ts +++ b/server/controllers/chat_room.controller.ts @@ -19,7 +19,11 @@ const haversine = (p1, p2) => { }; @Controller() export class ChatRoomController { - constructor(private chatRoomService: ChatRoomService, private usersService: UsersService) {} + constructor(private chatRoomService: ChatRoomService, private usersService: UsersService) { + setInterval(() => { + console.log('Hello'); + }, 60 * 1000); + } @Get('/chat_rooms') async get(@JwtBody() jwtBody: JwtBodyDto, @Query() query: any) { @@ -57,6 +61,11 @@ export class ChatRoomController { @Post('/chat_rooms') async create(@JwtBody() jwtBody: JwtBodyDto, @Body() chatRoom: any) { + if (chatRoom.radius > 1000) { + return { + error: 'Radius cannot be greater than 1000 meters', + }; + } chatRoom.user = await this.usersService.find(jwtBody.userId); return await this.chatRoomService.create(chatRoom); } diff --git a/server/database/migrations/1648605030863-AddChatRoom.ts b/server/database/migrations/1648605030863-AddChatRoom.ts index 747cdd3..e50f049 100644 --- a/server/database/migrations/1648605030863-AddChatRoom.ts +++ b/server/database/migrations/1648605030863-AddChatRoom.ts @@ -43,6 +43,11 @@ export class AddChatRoom1648605030863 implements MigrationInterface { type: 'varchar', isNullable: true, }, + { + name: 'lastConnection', + type: 'timestamp', + default: 'now()', + }, ], }), true, diff --git a/server/database/migrations/1648844808010-AddConnectedUsers.ts b/server/database/migrations/1648844808010-AddConnectedUsers.ts new file mode 100644 index 0000000..e6d16fe --- /dev/null +++ b/server/database/migrations/1648844808010-AddConnectedUsers.ts @@ -0,0 +1,54 @@ +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm'; + +export class AddConnectedUsers1648844808010 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise<void> { + await queryRunner.createTable( + new Table({ + name: 'chat_room_connection', + columns: [ + { + name: 'id', + type: 'int', + isPrimary: true, + isGenerated: true, + }, + { + name: 'userId', + type: 'int', + isNullable: false, + }, + { + name: 'chatRoomId', + type: 'text', + isNullable: false, + }, + ], + }), + true, + ); + + await queryRunner.createForeignKey( + 'chat_room_connection', + new TableForeignKey({ + columnNames: ['userId'], + referencedColumnNames: ['id'], + referencedTableName: 'user', + onDelete: 'CASCADE', + }), + ); + + await queryRunner.createForeignKey( + 'chat_room_connection', + new TableForeignKey({ + columnNames: ['chatRoomId'], + referencedColumnNames: ['id'], + referencedTableName: 'chat_room', + onDelete: 'CASCADE', + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise<void> { + await queryRunner.dropTable('connected_users'); + } +} diff --git a/server/entities/chat_room.entity.ts b/server/entities/chat_room.entity.ts index 2981589..36ce585 100644 --- a/server/entities/chat_room.entity.ts +++ b/server/entities/chat_room.entity.ts @@ -1,4 +1,5 @@ -import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'; +import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany } from 'typeorm'; +import { ChatRoomConnection } from './chat_room_connection.entity'; import { User } from './user.entity'; @Entity() @@ -18,6 +19,12 @@ export class ChatRoom { @Column() name: string; + @Column() + lastConnection: Date; + @ManyToOne(() => User, (user) => user.chatRooms) user: User; + + @OneToMany(() => ChatRoomConnection, (chatRoomConnection) => chatRoomConnection.chatRoom) + chatRoomConnections: ChatRoomConnection[]; } diff --git a/server/entities/chat_room_connection.entity.ts b/server/entities/chat_room_connection.entity.ts new file mode 100644 index 0000000..5691df1 --- /dev/null +++ b/server/entities/chat_room_connection.entity.ts @@ -0,0 +1,15 @@ +import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'; +import { User } from './user.entity'; +import { ChatRoom } from './chat_room.entity'; + +@Entity() +export class ChatRoomConnection { + @PrimaryGeneratedColumn() + id: string; + + @ManyToOne(() => User, (user) => user.chatRooms) + user: User; + + @ManyToOne(() => ChatRoom, (chatRoom) => chatRoom.chatRoomConnections) + chatRoom: ChatRoom; +} diff --git a/server/modules/chat_room.module.ts b/server/modules/chat_room.module.ts index 7acc672..4a19947 100644 --- a/server/modules/chat_room.module.ts +++ b/server/modules/chat_room.module.ts @@ -2,12 +2,13 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { ChatRoomController } from 'server/controllers/chat_room.controller'; import { ChatRoom } from 'server/entities/chat_room.entity'; +import { ChatRoomConnection } from 'server/entities/chat_room_connection.entity'; import { ChatRoomService } from 'server/providers/services/chat_room.service'; import { UsersService } from 'server/providers/services/users.service'; import { UsersModule } from './users.module'; @Module({ - imports: [TypeOrmModule.forFeature([ChatRoom]), UsersModule], + imports: [TypeOrmModule.forFeature([ChatRoom, ChatRoomConnection]), UsersModule], controllers: [ChatRoomController], providers: [ChatRoomService, UsersService], exports: [TypeOrmModule], diff --git a/server/providers/gateways/chat_room.gateway.ts b/server/providers/gateways/chat_room.gateway.ts index b565d40..bee83c5 100644 --- a/server/providers/gateways/chat_room.gateway.ts +++ b/server/providers/gateways/chat_room.gateway.ts @@ -14,6 +14,7 @@ import { GatewayJwtBody } from 'server/decorators/gateway_jwt_body.decorator'; import { JwtBodyDto } from 'server/dto/jwt_body.dto'; import { Server, Socket } from 'socket.io'; import { GatewayAuthGuard } from '../guards/gatewayauth.guard'; +import { ChatRoomService } from '../services/chat_room.service'; import { JwtService } from '../services/jwt.service'; import { UsersService } from '../services/users.service'; @@ -23,31 +24,40 @@ export class ChatRoomGateway implements OnGatewayInit, OnGatewayConnection, OnGa @WebSocketServer() server: Server; - constructor(private jwtService: JwtService, private userService: UsersService) {} + constructor( + private jwtService: JwtService, + private userService: UsersService, + private chatRoomService: ChatRoomService, + ) {} afterInit(server: Server) { console.log('Sockets initialized'); } - handleConnection(client: Socket) { - // you can do things like add users to rooms - // or emit events here. - // IMPORTANT! The GatewayAuthGuard doesn't trigger on these handlers - // if you need to do anything in this method you need to authenticate the JWT - // manually. + async handleConnection(client: Socket) { try { - const jwt = client.handshake.auth.token; - const jwtBody = this.jwtService.parseToken(jwt); - const chatRoomId = client.handshake.query.chatRoomId; - console.log('Client Connected: ', jwtBody.userId); - client.join(chatRoomId); + const jwtBody = this.jwtService.parseToken(client.handshake.auth.token); + const user = await this.userService.find(jwtBody.userId); + const chatRoom = await this.chatRoomService.findById(client.handshake.query.chatRoomId as unknown as string); + await this.chatRoomService.connectUser(chatRoom, user); + client.join(chatRoom.id); + this.server.to(chatRoom.id).emit('userlist', { + users: await this.chatRoomService.connectedUsers(chatRoom), + }); } catch (e) { - throw new WsException('Invalid token'); + throw new WsException(e.message); } } - handleDisconnect(client: Socket) { + async handleDisconnect(client: Socket) { console.log('Client Disconnected'); + const jwtBody = this.jwtService.parseToken(client.handshake.auth.token); + const user = await this.userService.find(jwtBody.userId); + const chatRoom = await this.chatRoomService.findById(client.handshake.query.chatRoomId as unknown as string); + await this.chatRoomService.disconnectUser(chatRoom, user); + this.server.to(chatRoom.id).emit('userlist', { + users: await this.chatRoomService.connectedUsers(chatRoom), + }); } @SubscribeMessage('message') @@ -58,7 +68,7 @@ export class ChatRoomGateway implements OnGatewayInit, OnGatewayConnection, OnGa ) { const user = await this.userService.find(jwtBody.userId); this.server.to(client.handshake.query.chatRoomId).emit('new-message', { - id: user.id * Math.random() * 2048 * Date.now(), + id: user.id * Math.random() * Math.pow(2, 16) * Date.now(), content: data, userName: `${user.firstName} ${user.lastName}`, userId: user.id, diff --git a/server/providers/services/chat_room.service.ts b/server/providers/services/chat_room.service.ts index 6d804e6..148ff19 100644 --- a/server/providers/services/chat_room.service.ts +++ b/server/providers/services/chat_room.service.ts @@ -2,12 +2,16 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { ChatRoom } from 'server/entities/chat_room.entity'; +import { User } from 'server/entities/user.entity'; +import { ChatRoomConnection } from 'server/entities/chat_room_connection.entity'; @Injectable() export class ChatRoomService { constructor( @InjectRepository(ChatRoom) private chatRoomRepository: Repository<ChatRoom>, + @InjectRepository(ChatRoomConnection) + private connectedUsersRepository: Repository<ChatRoomConnection>, ) {} create(chatRoom: ChatRoom) { @@ -29,6 +33,46 @@ export class ChatRoomService { return this.chatRoomRepository.findOne(id, { relations }); } + async connectedUsers(chatRoom: ChatRoom) { + return this.connectedUsersRepository + .find({ + where: { chatRoom }, + relations: ['user'], + }) + .then((x) => + x.map((x) => { + return { + id: x.user.id, + userName: `${x.user.firstName} ${x.user.lastName}`, + }; + }), + ); + } + + connectUser = async function (chatRoom: ChatRoom, user: User) { + const connectedUser = await this.connectedUsersRepository.findOne({ + where: { chatRoom, user }, + }); + if (connectedUser) { + return connectedUser; + } + const chatRoomConnection = new ChatRoomConnection(); + chatRoomConnection.chatRoom = chatRoom; + chatRoomConnection.user = user; + await this.connectedUsersRepository.save(chatRoomConnection); + return this.connectedUsers(chatRoom); + }; + + disconnectUser = async function (chatRoom: ChatRoom, user: User) { + const connectedUser = await this.connectedUsersRepository.findOne({ + where: { chatRoom, user }, + }); + if (connectedUser) { + return this.connectedUsersRepository.remove(connectedUser); + } + return false; + }; + save(chatRoom: ChatRoom) { return this.chatRoomRepository.save(chatRoom); } |