Skip to content

Conversation

@twalla26
Copy link
Collaborator

@twalla26 twalla26 commented Nov 5, 2024

백엔드 signaling server 구현

관련 이슈 번호

  • 작성자: J141_송수민
  • 작성 날짜: 2024.11.05

✅ 체크리스트

  • 코드가 정상적으로 작동하는지 확인했습니다.
  • 주요 변경사항에 대한 설명을 작성했습니다.
  • 코드 스타일 가이드에 따라 코드를 작성했습니다.

🧩 작업 내용

  • WebSocket과 socket.io를 이용한 signaling server 구현
    • join_room 이벤트
    • offer 이벤트
    • answer 이벤트
    • candidate 이벤트

📝 작업 상세 내역

웹소켓 연결 설정 및 해제 기능

  • 웹소켓이 연결되면 로그를 찍고, 연결이 해제되면 해당 방에 있던 나머지 사용자에게 퇴장 이벤트를 보낸다.
class SocketGateway implements OnGatewayConnection, OnGatewayDisconnect {
    @WebSocketServer()
    server: Server;

    private users: { [key: string]: User[] } = {}; // { '방 이름': [ { id: '소켓id', nickname: '유저 닉네임' }, ... ], ... }
    private socketToRoom: { [key: string]: string } = {}; // { '소켓id': '방 이름', ... }
    private maximum = 5; // 방 하나에 최대 5명 입장 가능

    handleConnection(socket: any) {
        console.log(`Client connected: ${socket.id}`);
    }

    handleDisconnect(socket: any) {
        console.log(`Client disconnected: ${socket.id}`);
        const roomID = this.socketToRoom[socket.id];
        if (roomID) {
            const room = this.users[roomID];
            if (room) {
                this.users[roomID] = room.filter(
                    (user) => user.id !== socket.id
                );
                if (this.users[roomID].length === 0) {
                    delete this.users[roomID];
                } else {
                    this.server.to(roomID).emit("user_exit", { id: socket.id });
                }
            }
        }
    }
}

signaling server 구현

  1. 방 참여 처리 (handleJoinRoom):
    • 사용자가 방에 들어올 때, 현재 방의 인원 수를 확인하여 최대 인원을 초과하면 "room_full" 이벤트를 통해 클라이언트에 알린다.
    • 방에 새로운 사용자를 추가하고, 현재 방에 있는 사용자 목록을 클라이언트에 전송한다.
  2. offer 처리 (handleOffer):
    • 사용자가 다른 사용자에게 WebRTC 연결 요청을 위한 오퍼를 전송한다.
    • 수신자에게 오퍼와 함께 송신자의 ID와 닉네임을 포함하여 전송한다.
  3. answer 처리 (handleAnswer):
    • 상대방이 오퍼에 대한 응답을 보내면, 이를 수신자에게 전달한다.
    • 응답과 함께 송신자의 ID를 포함하여 전송한다.
  4. candidate 처리 (handleCandidate):
    • ICE 후보가 생성되면 이를 해당 후보를 수신해야 하는 사용자에게 전달한다.
    • 수신자에게 후보 정보와 송신자의 ID를 함께 전송한다.

📌 테스트 및 검증 결과

웹소켓 연결 설정 및 해제 기능

image

signaling server 구현

  1. 방 참여, 퇴장 처리

    1. join_room
      image
    • 방에 입장하면 해당 방의 기존 사람들의 socket id와 nickname도 확인할 수 있다.
    1. room_full
      image
    • 방에 6번째로 접근한 사람에게는 room_full 이벤트가 전송된다.
    1. user_exit
      image
    • 특정 사용자의 연결이 해제되면 해당 방의 나머지 사용자들에게 user_exit 이벤트가 전송된다.
  2. offer 처리

  • nickname1이 nickname2에게 offer를 전송한다.
    image
  • nickname2가 nickname1의 offer를 getOffer 이벤트로 전송받았다.
    image
  • sdp 데이터는 예시로서 작성했다.
  1. answer 처리
  • nickname1이 nickname2에게 answer를 전송한다.
    image
  • nickname2가 nickname1의 answer를 getAnswer로 전송받았다.
    image
  1. candidate 처리
  • nickname1이 nickname2에게 candidate을 전송한다.
    image
  • nickname2가 nickname1의 candidate을 전송 받았다.
    image

💬 다음 작업 또는 논의 사항

  • postman도 좋지만 다른 웹소켓 코드 테스트 방법도 알아보고 싶다.

📎 참고 자료

@ShipFriend0516
Copy link
Member

PR을 너무 잘 써주셔서 이해가 잘 됐습니다. 예상보다 빠르게 구현이 되었네요! nestjs 코드리뷰는 처음인데 덕분에 nestjs 문법도 알 수 있어서 좋았습니다 👍👍

Copy link
Member

@yiseungyun yiseungyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 상세하게 써주시고, 결과 스크린 샷까지 넣어주셔서 잘 읽을 수 있었습니다. 👍
spec.ts 파일에 테스트하는 코드가 있어, 찾아보니 nest에서는 *.spec.ts로 테스트 파일 명을 정하는 걸 알게되었네요.

@yiseungyun yiseungyun self-requested a review November 5, 2024 11:07
Copy link
Member

@yiseungyun yiseungyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nest를 써보지 않았음에도 코드가 깔끔해서 읽기 쉬웠던거 같습니다. 수고 많으셨습니다. ☃️

Copy link
Collaborator

@blu3fishez blu3fishez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일단은 간단한 예제를 배포를 해서 같이 테스트를 해봅시다!

이번에는 Approve 인데.. any 타입은 절대 쓰시면 안됩니다..ㅠㅠ

Comment on lines +29 to +31
handleConnection(socket: any) {
console.log(`Client connected: ${socket.id}`);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any 타입 절대 쓰시면 안됩니다...!

socket으로 어떤 데이터가 오는지 모르는 경우 unknown 타입을 사용해서 타입가드로 내로잉하셔야할 거에요..!

관련 개념 찾아보시면 좋을 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyunknown 타입!! 학습하겠습니다.

Comment on lines +25 to +27
private users: { [key: string]: User[] } = {};
private socketToRoom: { [key: string]: string } = {};
private maximum = 5;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

임시로 외부 변수 사용하신거 일단은 좋습니다~ 개념이 어렵다보니 일단 심플하게 그냥 하시는 게 좋죠!

이걸 같이 Redis 로 뺄 방법을 같이 공부해봅시다!!

@twalla26 twalla26 merged commit 738a1a2 into boostcampwm-2024:feature/signaling-server Nov 5, 2024
@twalla26 twalla26 self-assigned this Nov 5, 2024
@twalla26 twalla26 deleted the feature/signaling-server branch November 11, 2024 05:14
@twalla26 twalla26 changed the title Signaling server 구현 [Feat]signaling server 구현 Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants