Skip to content

Commit

Permalink
merge: [BE] 서버 리펙토링 및 시그널링 서버 에러 제거 #121
Browse files Browse the repository at this point in the history
[BE]: 서버 리펙토링 및 시그널링 서버 에러 제거
  • Loading branch information
Gseungmin authored Nov 27, 2023
2 parents 1d3cc71 + 8b469c7 commit d0709bc
Show file tree
Hide file tree
Showing 18 changed files with 311 additions and 39 deletions.
2 changes: 2 additions & 0 deletions backEnd/center/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export const EVENT = {
REGISTER: 'register',
SIGNALING: 'signaling',
};

export const USE_FULL = 100;
7 changes: 3 additions & 4 deletions backEnd/center/src/events/events.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { HttpCode, HttpStatus, Injectable, OnModuleInit } from '@nestjs/common';
import { HttpStatus, Injectable, OnModuleInit } from '@nestjs/common';
import Redis from 'ioredis';
import { ResponseUrlDto } from 'src/connections/dto/response-url.dto';
import { JoinRoomDto } from 'src/connections/dto/join-room.dto';
import {
URLNotFoundException,
ValidateDtoException,
} from 'src/common/exception/exception';
import { ERRORS, EVENT } from 'src/common/utils';
import { ERRORS, EVENT, USE_FULL } from 'src/common/utils';
import { ResponseDto } from 'src/common/dto/common-response.dto';

@Injectable()
Expand Down Expand Up @@ -55,7 +54,7 @@ export class EventsService implements OnModuleInit {

private handleSignaling(url: string, usages: number) {
const nextServer = this.returnUrl;
const minUsages = this.serverToCpus.get(nextServer);
const minUsages = this.serverToCpus.get(nextServer) || USE_FULL;

if (usages < minUsages) {
this.returnUrl = url;
Expand Down
4 changes: 3 additions & 1 deletion backEnd/chat/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ChatGateway } from './chat/chat.gateway';
import { ChatService } from './chat/chat.service';
import { ChatModule } from './chat/chat.module';

@Module({
imports: [
Expand All @@ -21,8 +22,9 @@ import { ChatService } from './chat/chat.service';
}),
inject: [ConfigService],
}),
ChatModule,
],
controllers: [AppController],
providers: [AppService, ChatGateway, ChatService],
providers: [AppService],
})
export class AppModule {}
76 changes: 76 additions & 0 deletions backEnd/chat/src/chat/chat.gateway.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ChatGateway } from './chat.gateway';
import { ChatService } from './chat.service';
import Redis from 'ioredis';
import { RedisModule, getRedisToken } from '@liaoliaots/nestjs-redis';
import { MessageDto } from './dto/message.dto';
import { Socket } from 'socket.io';
import { WsException } from '@nestjs/websockets';

describe('ChatGateway', () => {
let gateway: ChatGateway;
let chatService: ChatService;
let redisClient: Redis;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
RedisModule.forRoot({
config: {
host: 'localhost',
port: 6379,
},
}),
],
providers: [ChatGateway, ChatService],
}).compile();

gateway = module.get<ChatGateway>(ChatGateway);
chatService = module.get<ChatService>(ChatService);
redisClient = module.get<Redis>(getRedisToken('default'));
});

afterEach(async () => {
await redisClient.flushall();
});

describe('Redis', () => {
it('레디스와 연결에 성공한다.', async () => {
expect(redisClient).toBeDefined();
const response = await redisClient.ping();
expect(response).toBe('PONG');
});
});

describe('sendMessage', () => {
it('메시지를 보냈을때 room 정보가 없으면 예외가 발생한다.', async () => {
//GIVEN
const testMessageDto: MessageDto = {
room: '',
message: 'testMessage',
};
const testSocket = { id: '12345' } as unknown as Socket;

// WHEN
const messageHandling = gateway.handleMessage(testMessageDto, testSocket);

// THEN
await expect(messageHandling).rejects.toThrow(WsException);
});

it('메시지를 보냈을때 message 정보가 없으면 예외가 발생한다.', async () => {
//GIVEN
const testMessageDto: MessageDto = {
room: 'testRoom',
message: '',
};
const testSocket = { id: '12345' } as unknown as Socket;

// WHEN
const messageHandling = gateway.handleMessage(testMessageDto, testSocket);

// THEN
await expect(messageHandling).rejects.toThrow(WsException);
});
});
});
36 changes: 31 additions & 5 deletions backEnd/chat/src/chat/chat.gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
ConnectedSocket,
MessageBody,
OnGatewayConnection,
OnGatewayDisconnect,
SubscribeMessage,
WebSocketGateway,
WebSocketServer,
WsException,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { Logger } from '@nestjs/common';
Expand All @@ -14,11 +16,11 @@ import { JoinRoomDto } from './dto/join-room.dto';
import { LeaveRoomDto } from './dto/leave-room.dto';
import { MessageDto } from './dto/message.dto';
import * as os from 'os';
import { SOCKET, SOCKET_EVENT } from 'src/commons/utils';
import { ERRORS, SOCKET, SOCKET_EVENT } from '../commons/utils';
import { ChatService } from './chat.service';

@WebSocketGateway({ namespace: SOCKET.NAME_SPACE, cors: true })
export class ChatGateway implements OnGatewayConnection {
export class ChatGateway implements OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer()
server: Server;

Expand All @@ -41,11 +43,17 @@ export class ChatGateway implements OnGatewayConnection {
this.logger.log(`Instance ${this.instanceId} - connected: ${socket.id}`);
}

handleDisconnect(socket: Socket) {
this.logger.log(`Instance ${this.instanceId} - disconnected: ${socket.id}`);
}

@SubscribeMessage(SOCKET_EVENT.JOIN_ROOM)
handleJoin(
@MessageBody() data: JoinRoomDto,
@ConnectedSocket() socket: Socket,
) {
this.logger.log(`Instance ${this.instanceId} - joinRoom: ${socket.id}`);

const { room } = data;
this.chatService.validateRoom(room);

Expand All @@ -71,6 +79,8 @@ export class ChatGateway implements OnGatewayConnection {
@MessageBody() data: LeaveRoomDto,
@ConnectedSocket() socket: Socket,
) {
this.logger.log(`Instance ${this.instanceId} - leaveRoom: ${socket.id}`);

const { room } = data;
this.chatService.validateRoom(room);

Expand All @@ -86,15 +96,31 @@ export class ChatGateway implements OnGatewayConnection {
}

@SubscribeMessage(SOCKET_EVENT.SEND_MESSAGE)
async handleMessage(@MessageBody() data: MessageDto) {
const { room, message } = data;
async handleMessage(
@MessageBody() data: MessageDto,
@ConnectedSocket() socket: Socket,
) {
this.logger.log(`Instance ${this.instanceId} - sendMessage: ${socket.id}`);

const { room, message, nickname } = data;

this.chatService.validateRoom(room);
this.chatService.validateMessage(message);
this.chatService.validateNickname(nickname);

const response = {
message: message,
nickname: nickname,
socketId: socket.id,
};
this.publisherClient.publish(room, JSON.stringify(response));

try {
await this.publisherClient.publish(room, JSON.stringify(response));
} catch (error) {
throw new WsException({
statusCode: ERRORS.FAILED_PUBLISHING.statusCode,
message: ERRORS.FAILED_PUBLISHING.message,
});
}
}
}
6 changes: 6 additions & 0 deletions backEnd/chat/src/chat/chat.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';
import { ChatService } from './chat.service';

@Module({ providers: [ChatGateway, ChatService] })
export class ChatModule {}
21 changes: 21 additions & 0 deletions backEnd/chat/src/chat/chat.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ChatService } from './chat.service';
import { WsException } from '@nestjs/websockets';

describe('ChatService', () => {
let service: ChatService;
Expand All @@ -15,4 +16,24 @@ describe('ChatService', () => {
it('should be defined', () => {
expect(service).toBeDefined();
});

describe('validateRoom', () => {
it('방 이름을 입력하면 예외가 발생하지 않는다.', () => {
expect(() => service.validateRoom('room1')).not.toThrow();
});

it('방 이름을 입력하지 않으면 예외가 발생한다.', () => {
expect(() => service.validateRoom('')).toThrow(WsException);
});
});

describe('validateMessage', () => {
it('메시지를 입력하면 예외가 발생하지 않는다.', () => {
expect(() => service.validateMessage('message1')).not.toThrow();
});

it('메시지를 입력하지 않으면 예외가 발생한다.', () => {
expect(() => service.validateMessage('')).toThrow(WsException);
});
});
});
11 changes: 10 additions & 1 deletion backEnd/chat/src/chat/chat.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable, HttpStatus } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';
import { ERRORS } from 'src/commons/utils';
import { ERRORS } from '../commons/utils';

@Injectable()
export class ChatService {
Expand All @@ -21,4 +21,13 @@ export class ChatService {
});
}
}

validateNickname(nickname: string) {
if (!nickname) {
throw new WsException({
statusCode: ERRORS.ROOM_EMPTY.statusCode,
message: ERRORS.ROOM_EMPTY.message,
});
}
}
}
1 change: 1 addition & 0 deletions backEnd/chat/src/chat/dto/message.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export class MessageDto {
room: string;
message: string;
nickname: string;
}
8 changes: 8 additions & 0 deletions backEnd/chat/src/commons/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export const SOCKET_EVENT = {
};

export const ERRORS = {
NICKNAME_EMPTY: {
statusCode: HttpStatus.BAD_REQUEST,
message: '닉네임을 입력해주세요.',
},
ROOM_EMPTY: {
statusCode: HttpStatus.BAD_REQUEST,
message: '방 이름을 입력해주세요.',
Expand All @@ -22,4 +26,8 @@ export const ERRORS = {
statusCode: HttpStatus.BAD_REQUEST,
message: '메시지를 입력해주세요.',
},
FAILED_PUBLISHING: {
statusCode: HttpStatus.BAD_REQUEST,
message: '메시지를 PUB하는데 실패했습니다.',
},
};
5 changes: 3 additions & 2 deletions backEnd/signaling/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { WebRtcGateway } from './webRTC/web-rtc.gateway';
import { WinstonLogger } from './common/logger/winstonLogger.service';
import { RedisModule } from '@liaoliaots/nestjs-redis';
import { EventsModule } from './events/events.module';
import { WebRtcModule } from './webRTC/web-rtc.module';

@Module({
imports: [
Expand All @@ -23,8 +23,9 @@ import { EventsModule } from './events/events.module';
inject: [ConfigService],
}),
EventsModule,
WebRtcModule,
],
controllers: [AppController],
providers: [AppService, WebRtcGateway, WinstonLogger],
providers: [AppService, WinstonLogger],
})
export class AppModule {}
28 changes: 27 additions & 1 deletion backEnd/signaling/src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { HttpStatus } from '@nestjs/common';

export const SOCKET = {
NAME_SPACE: 'signaling',
MAXIMUM: 4,
ROOM_FULL: 4,
ROOM_EMPTY: 0,
};

export const SOCKET_EVENT = {
Expand All @@ -18,3 +21,26 @@ export const SOCKET_EVENT = {
GET_ANSWER: 'getAnswer',
GET_CANDIDATE: 'getCandidate',
};

export const ERRORS = {
ROOM_FULL: {
statusCode: HttpStatus.BAD_REQUEST,
message: '해당 방에 인원이 가득찼습니다.',
},
FAIL_JOIN_ROOM: {
statusCode: HttpStatus.BAD_REQUEST,
message: 'ROOM JOIN에 실패하였습니다.',
},
FAIL_OFFER: {
statusCode: HttpStatus.BAD_REQUEST,
message: 'OFFER에 실패하였습니다.',
},
FAIL_ANSWER: {
statusCode: HttpStatus.BAD_REQUEST,
message: 'ANSWER에 실패하였습니다.',
},
FAIL_CANDIDATE: {
statusCode: HttpStatus.BAD_REQUEST,
message: 'CANDIDATE에 실패하였습니다.',
},
};
3 changes: 1 addition & 2 deletions backEnd/signaling/src/events/events.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Module } from '@nestjs/common';
import { EventsService } from './events.service';
import { WebRtcGateway } from 'src/webRTC/web-rtc.gateway';

@Module({
providers: [EventsService, WebRtcGateway],
providers: [EventsService],
exports: [EventsService],
})
export class EventsModule {}
Loading

0 comments on commit d0709bc

Please sign in to comment.