Skip to content

Commit

Permalink
Merge pull request #112 from boostcampwm-2024/feat-be-#107-broadcast_…
Browse files Browse the repository at this point in the history
…start_api

[FEAT] 기존 host 키 생성 리팩토링 / rtmp 스트림키 교환 API 작성
  • Loading branch information
i3kae authored Nov 16, 2024
2 parents a86aacb + 5103dac commit 06ffe8c
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 35 deletions.
9 changes: 4 additions & 5 deletions backend/mainServer/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller.js';
import { AppService } from './app.service.js';
import { HostController } from './host/host.controller.js';
import { HostService } from './host/host.service.js';
import { HostModule } from './host/host.module.js';

@Module({
imports: [],
controllers: [AppController, HostController],
providers: [AppService, HostService],
imports: [HostModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
6 changes: 6 additions & 0 deletions backend/mainServer/src/host/dto/hostKeyPairDto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';

export class hostKeyPairDto {
@ApiProperty({example: 'this_is_userId', description: '클라이언트마다 가지는 랜덤한 userId 값'})
userId: string = '';
}
44 changes: 37 additions & 7 deletions backend/mainServer/src/host/host.controller.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,60 @@
import { Controller, Post, Req, Res, HttpException, HttpStatus, Body } from '@nestjs/common';
import { keyGenerateRequestDto, HostService } from './host.service.js';
import { Controller, Post, Get, Req, Res, HttpException, HttpStatus, Body, Query } from '@nestjs/common';
import { HostService } from './host.service.js';
import { hostKeyPairDto } from './dto/hostKeyPairDto.js';
import { Request, Response } from 'express';
import { ApiCreatedResponse, ApiOperation, ApiTags } from '@nestjs/swagger';

@Controller('host')
@ApiTags('Host API')
export class HostController {
constructor(private readonly hostService: HostService) {}
_inMemory: { [key: string]: string };
constructor(private readonly hostService: HostService) {
this._inMemory = {
'web22':'web22_session'
};
}

@Post('/key')
@ApiOperation({ summary: 'Host Stream, Session Key Generate API', description: 'Host용 스트림키와 세션키를 생성합니다.' })
@ApiCreatedResponse({ description: '스트림키, 세션키를 생성한다.', type: Array<string> })
async generateStreamKey(@Body() requestDto: keyGenerateRequestDto, @Req() req: Request, @Res() res: Response) {
@ApiCreatedResponse({ description: '스트림키, 세션키를 생성한다.' })
async generateStreamKey(@Body() requestDto: hostKeyPairDto, @Req() req: Request, @Res() res: Response) {
try {
const host = req.headers['host'] as string;
const contentType = req.headers['content-type'];

if (!host || !contentType || !requestDto.uuid) {
if (!host || !contentType || !requestDto.userId) {
throw new HttpException('Bad Request', HttpStatus.BAD_REQUEST);
}
if (contentType !== 'application/json') {
throw new HttpException('Content-Type must be application/json', HttpStatus.BAD_REQUEST);
}

const [streamKey, sessionKey] = await this.hostService.generateStreamKey(requestDto);
res.status(HttpStatus.OK).json({ 'stream-key': streamKey, 'session-key':sessionKey });
this._inMemory[streamKey] = sessionKey;
console.log(this._inMemory);
res.status(HttpStatus.OK).json({ 'streamKey': streamKey, 'sessionKey':sessionKey });
} catch (error) {
if ((error as { status: number }).status === 400) {
res.status(HttpStatus.BAD_REQUEST).json({
error: (error as { response: Response }).response
});
}
else {
res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
error: 'Server logic error',
});
}
}
}

@Get('/session')
@ApiOperation({ summary: 'Session Key To Session Key API', description: 'Host의 Stream Key를 통해 Session Key를 찾습니다.' })
@ApiCreatedResponse({ description: '스트림 키를 통해 세션키를 전달 받습니다.' })
async findSession(@Query('streamKey') streamKey: string, @Req() req: Request, @Res() res: Response) {
try {
if (!(streamKey in this._inMemory))
throw new HttpException('Bad Request', HttpStatus.BAD_REQUEST);
res.status(HttpStatus.OK).json({'session-key':this._inMemory[streamKey] });
} catch (error) {
if ((error as { status: number }).status === 400) {
res.status(HttpStatus.BAD_REQUEST).json({
Expand Down
9 changes: 9 additions & 0 deletions backend/mainServer/src/host/host.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { HostController } from './host.controller.js';
import { HostService } from './host.service.js';

@Module({
controllers: [HostController],
providers: [HostService],
})
export class HostModule {}
22 changes: 6 additions & 16 deletions backend/mainServer/src/host/host.service.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { Injectable } from '@nestjs/common';
import dotenv from 'dotenv';
import path from 'path';
import crypto from 'crypto';
import { ApiProperty } from '@nestjs/swagger';

export class keyGenerateRequestDto {
@ApiProperty({example: 'this_is_uuid', description: '클라이언트마다 가지는 랜덤한 uuid 값'})
uuid: string = '';
}

function generateRandomKey(uuid: string, salt: string) {
const hash = crypto.createHmac('sha256', salt).update(uuid).digest('hex');
return hash;
}
import { Injectable } from '@nestjs/common';
import { hostKeyPairDto } from './dto/hostKeyPairDto.js';
import { randomKey } from '../util/generator.js';

@Injectable()
export class HostService {
async generateStreamKey(requestDto: keyGenerateRequestDto): Promise<Array<string>> {
async generateStreamKey(requestDto: hostKeyPairDto): Promise<Array<string>> {
dotenv.config({path: path.resolve('../.env')});
const streamKey = generateRandomKey(requestDto.uuid, process.env.STREAM_KEY_SALT || '');
const sessionKey = generateRandomKey(requestDto.uuid, process.env.SESSION_KEY_SALT || '');
const streamKey = randomKey(requestDto.userId, process.env.STREAM_KEY_SALT || '');
const sessionKey = randomKey(requestDto.userId, process.env.SESSION_KEY_SALT || '');
return [streamKey, sessionKey];
}
}
7 changes: 7 additions & 0 deletions backend/mainServer/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import { setupSwagger } from './util/swagger.js';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
setupSwagger(app);

app.enableCors({
origin: '*', // 프론트엔드 URL로 설정
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE', // 허용할 HTTP 메서드
credentials: true, // 필요에 따라 true로 설정
});

await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
6 changes: 6 additions & 0 deletions backend/mainServer/src/util/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import crypto from 'crypto';

export function randomKey(uuid: string, salt: string, length: number = 20) {
const hash = crypto.createHmac('sha256', salt).update(uuid).digest('hex');
return hash.substring(0, length);
}
11 changes: 7 additions & 4 deletions backend/mainServer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"declaration": true,
Expand All @@ -10,13 +9,17 @@
"target": "ESNext",
"sourceMap": true,
"outDir": "./.dist",
"baseUrl": "./",
"baseUrl": ".",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
"noFallthroughCasesInSwitch": false,
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true
},
"exclude": ["**/*spec.ts"]
}
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2186,8 +2186,8 @@ __metadata:
linkType: hard

"@nestjs/swagger@npm:^8.0.5":
version: 8.0.5
resolution: "@nestjs/swagger@npm:8.0.5"
version: 8.0.7
resolution: "@nestjs/swagger@npm:8.0.7"
dependencies:
"@microsoft/tsdoc": "npm:^0.15.0"
"@nestjs/mapped-types": "npm:2.0.6"
Expand All @@ -2209,7 +2209,7 @@ __metadata:
optional: true
class-validator:
optional: true
checksum: 10c0/7d5b0b2503dd674c467218cd46c5b2a5389a67183217a5542ed6b7421045cec231a889588413c6a8e00a7ebc96a89fa0c3374fadc0e24d643743630095b37b82
checksum: 10c0/64574e8322d4021a45922d11b6e4f7438008c4d05a2a8e61f29c18ab60d404e4a0579a1aea862f683af5b77b32266d7823f3512a0e194c856f7cdb5eee63e84c
languageName: node
linkType: hard

Expand Down

0 comments on commit 06ffe8c

Please sign in to comment.