Skip to content

Commit

Permalink
[FE][hotfix] WebRTC 로직 리팩터링 (#79)
Browse files Browse the repository at this point in the history
* refactor: JS 접근 제어자로 변경

* refactor: WebRTC 코드 리팩터링 및 렌더링 문제 일부 해결

* docs: README.md 업데이트
  • Loading branch information
studioOwol authored Nov 11, 2024
1 parent a86c705 commit 59832d9
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 211 deletions.
9 changes: 8 additions & 1 deletion fe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@

### 새로운 게임방이 추가될 때 순서대로 추가되지 않음

### 게임 페이지에서 새로고침하면 렌더링이 되지 않음
### 게임 페이지에서 새로고침하면 렌더링이 완전히 되지 않음

- VolumeBar `defaultValue` state 업데이트가 연속적으로 발생할 수 있는 구조
- Controlled Component? Uncontrolled Component? 혼용하면 무한 상태 업데이트 루프 발생?

## 게임 페이지에서 새로고침하면 players 방장을 제외하고 사라짐, 마이크도 안 됨

- 새로고침이 아주 문제다!
74 changes: 74 additions & 0 deletions fe/src/hooks/useGameRoom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { gameSocket } from '@/services/gameSocket';
import { getRoomsQuery } from '@/stores/queries/getRoomsQuery';
import useRoomStore from '@/stores/zustand/useRoomStore';
import { useCallback, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

export const useGameRoom = (roomId: string | undefined) => {
const navigate = useNavigate();
const setCurrentRoom = useRoomStore((state) => state.setCurrentRoom);
const { data: rooms, isLoading } = getRoomsQuery();

// 초기 설정 및 소켓 연결 관리
useEffect(() => {
// 로딩 중이면 리턴
if (isLoading) return;

// roomId나 rooms가 없으면 홈으로
if (!roomId || !rooms) {
navigate('/', { replace: true });
return;
}

const room = rooms.find((r) => r.roomId === roomId);
if (!room) {
navigate('/', { replace: true });
return;
}

// 소켓 연결 및 초기 설정
const initializeRoom = async () => {
try {
// 1. 소켓 연결
if (!gameSocket.socket?.connected) {
gameSocket.connect();
}

// 2. 방 설정
setCurrentRoom(room);

// 3. 소켓 재연결 (새로고침 대응)
await gameSocket.joinRoom(
roomId,
room.players[room.players.length - 1]
);
} catch (error) {
console.error('Failed to initialize room:', error);
navigate('/', { replace: true });
}
};

initializeRoom();

// Cleanup
return () => {
if (gameSocket.socket?.connected) {
gameSocket.disconnect();
}
setCurrentRoom(null);
};
}, [roomId, rooms, isLoading]);

// 방 나가기
const leaveRoom = useCallback(() => {
if (gameSocket.socket?.connected) {
gameSocket.disconnect();
}
setCurrentRoom(null);
navigate('/', { replace: true });
}, [navigate, setCurrentRoom]);

return {
leaveRoom,
};
};
83 changes: 83 additions & 0 deletions fe/src/hooks/useRoomActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { useCallback } from 'react';
import { gameSocket } from '@/services/gameSocket';
import { signalingSocket } from '@/services/signalingSocket';

export const useRoomActions = () => {
const createRoom = useCallback(
async (roomName: string, hostNickname: string) => {
try {
// 1. 게임 소켓 연결
gameSocket.connect();

// 2. 오디오 스트림 설정 및 방 생성
const stream = await gameSocket.createRoom(roomName, hostNickname);

// 3. 시그널링 소켓 설정
signalingSocket.connect();
signalingSocket.setLocalStream(stream);

// 4. 방 생성 성공 시 시그널링 룸 참여
const onRoomCreated = (room) => {
signalingSocket.joinSignalingRoom(room.roomId, hostNickname);
gameSocket.socket?.off('roomCreated', onRoomCreated);
};

gameSocket.socket?.on('roomCreated', onRoomCreated);
} catch (error) {
console.error('방 생성 실패:', error);
throw error;
}
},
[]
);

const joinRoom = useCallback(
async (roomId: string, playerNickname: string) => {
try {
// 1. 게임 소켓 연결
gameSocket.connect();

// 2. 오디오 스트림 설정 및 방 참여
const stream = await gameSocket.joinRoom(roomId, playerNickname);

// 3. 시그널링 소켓 설정
signalingSocket.connect();
signalingSocket.setLocalStream(stream);

// 4. 방 참여 성공 시 시그널링 룸 참여
const onUpdateUsers = (players) => {
if (players.includes(playerNickname)) {
signalingSocket.joinSignalingRoom(roomId, playerNickname);
gameSocket.socket?.off('updateUsers', onUpdateUsers);
}
};

gameSocket.socket?.on('updateUsers', onUpdateUsers);
} catch (error) {
console.error('방 참여 실패:', error);
throw error;
}
},
[]
);

const leaveRoom = useCallback(() => {
signalingSocket.disconnect();
gameSocket.disconnect();
}, []);

const toggleAudio = useCallback((enabled: boolean) => {
if (gameSocket['#audioStream']) {
gameSocket['#audioStream'].getAudioTracks().forEach((track) => {
track.enabled = enabled;
});
}
}, []);

return {
createRoom,
joinRoom,
leaveRoom,
toggleAudio,
};
};
2 changes: 1 addition & 1 deletion fe/src/pages/GamePage/PlayerList/VolumeBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const VolumeBar = ({ isOn }: AudioControlProps) => {
<HiSpeakerXMark className="h-4 w-4 text-muted-foreground" />
)}
<Slider
defaultValue={[volume]}
value={[volume]}
max={100}
step={1}
className="w-24"
Expand Down
21 changes: 18 additions & 3 deletions fe/src/pages/GamePage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import useRoomStore from '@/stores/zustand/useRoomStore';
import PlayerList from './PlayerList/PlayerList';
import { getRoomsQuery } from '@/stores/queries/getRoomsQuery';
import { useRoomActions } from '@/hooks/useRoomActions';

const GamePage = () => {
const [isAudioOn, setIsAudioOn] = useState(true);
const { roomId } = useParams();
const { data: rooms } = getRoomsQuery();
const { leaveRoom } = useRoomActions();
const { currentRoom, setCurrentRoom } = useRoomStore();
const navigate = useNavigate();

// 방 정보 업데이트 및 WebRTC 연결 설정
useEffect(() => {
if (rooms && roomId) {
if (rooms && roomId && (!currentRoom || currentRoom.roomId !== roomId)) {
const room = rooms.find((r) => r.roomId === roomId);
if (room) {
setCurrentRoom(room);
} else {
// 방을 찾을 수 없는 경우
navigate('/');
}
}
}, [rooms, roomId]);
}, [rooms, roomId, currentRoom]);

// 페이지 나가기 전에 연결 정리
useEffect(() => {
return () => {
console.log('Cleaning up room connections');
leaveRoom();
};
}, [leaveRoom]);

if (!currentRoom) return null;

Expand Down
Loading

0 comments on commit 59832d9

Please sign in to comment.