Skip to content

Commit

Permalink
[FE] WebRTC Mesh 방식 구현 해치웠다. (#88)
Browse files Browse the repository at this point in the history
* fix: hotfix-fe-#70-1 상태로 되돌리기

* refactor: RoomPage가 렌더링될 때 소켓 연결되도록

StrictMode useEffect 2번 호출돼서 제거

* refactor: TS 접근제어자로 변경

validateSocket 대신 소켓 연결 여부를 묻는 메서드로 변경

* chore: 변수명, 디렉터리명 변경

* chore: 타입 지정 및 상수화

오타 수정

* refactor: WebRTC 로직 리팩터링

* refactor: gameSocket에서 마이크 권한 요청 로직 제거

* refactor: Dialog 컴포넌트에서 소켓 연결 및 상태 가져오기

* chore: WebRTC 오디오 및 관련 리소스 정리 로직 메서드 분리

* docs: README.md 업데이트
  • Loading branch information
studioOwol authored Nov 13, 2024
1 parent 59832d9 commit 083c5a5
Show file tree
Hide file tree
Showing 22 changed files with 509 additions and 498 deletions.
Binary file added .DS_Store
Binary file not shown.
14 changes: 13 additions & 1 deletion fe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
- VolumeBar `defaultValue` state 업데이트가 연속적으로 발생할 수 있는 구조
- Controlled Component? Uncontrolled Component? 혼용하면 무한 상태 업데이트 루프 발생?

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

- 새로고침이 아주 문제다!

### 개발 환경에서 잘 실행되다가 배포한 후 제대로 실행이 안 됨

- 빌드된 것은 잘 되는데.. `npm run dev` 하면 제대로 동작하지 않음
- JS 접근제어자 #을 써서 그런가 의심.. (확실하지 않음)
- 해결하지 못해서 잘 동작하던 상태로 되돌리고 진행🥲

### 방을 생성한 사용자만 currentRoom 상태가 Store에 저장 돼서, 이미 생성된 방에 입장하려는 사용자는 currentRoom에 저장된 상태가 없음

- signalingSocket.joinRoom을 하려면 현재 room을 전달해 주어야 한다. 그런데 저장된 currentRoom이 없다.
- getRoomsQuery로 방 목록을 가져오고 roomId에 해당하는 room을 찾은 후 상태를 저장하고 signalingSocket에 전달하도록 함.
- JoinDialog에서도 currentRoom을 구독하도록 하면 안 되려나..? 뭔가 방법이 있을 것 같은데,,
2 changes: 1 addition & 1 deletion fe/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import './App.css';
import RoomPage from './pages/RoomPage';
import RoomPage from './pages/RoomListPage';
import GamePage from './pages/GamePage';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

Expand Down
24 changes: 24 additions & 0 deletions fe/src/constants/webRTC.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const STUN_SERVERS = Object.freeze({
iceServers: [
{
urls: 'stun:coturn.clovapatra.com:3478',
},
{
urls: 'turn:coturn.clovapatra.com:3478',
username: 'test',
credential: 'bestcompanynaver',
},
],
});

export const MEDIA_CONSTRAINTS = Object.freeze({
audio: {
echoCancellation: true, // 에코 제거
noiseSuppression: true, // 노이즈 제거
autoGainControl: true, // 자동 게인 제어
channelCount: 1, // 모노 채널
sampleRate: 16000, // 16kHz 샘플레이트
sampleSize: 16, // 16비트 샘플 크기
},
video: false, // 비디오 비활성화
});
74 changes: 0 additions & 74 deletions fe/src/hooks/useGameRoom.ts

This file was deleted.

83 changes: 0 additions & 83 deletions fe/src/hooks/useRoomActions.ts

This file was deleted.

14 changes: 5 additions & 9 deletions fe/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App.tsx';

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
createRoot(document.getElementById('root')!).render(<App />);
1 change: 0 additions & 1 deletion fe/src/pages/GamePage/PlayerList/Player.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Card, CardContent } from '@/components/ui/card';
import { PlayerProps } from '@/types/playerTypes';
import { BsMicFill, BsMicMuteFill } from 'react-icons/bs';
import { FaCrown } from 'react-icons/fa6';
import VolumeBar from './VolumeBar';

Expand Down
19 changes: 2 additions & 17 deletions fe/src/pages/GamePage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,21 @@ 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 && (!currentRoom || currentRoom.roomId !== roomId)) {
if (rooms && roomId) {
const room = rooms.find((r) => r.roomId === roomId);
if (room) {
setCurrentRoom(room);
} else {
// 방을 찾을 수 없는 경우
navigate('/');
}
}
}, [rooms, roomId, currentRoom]);

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

if (!currentRoom) return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ const RoomDialog = ({ open, onOpenChange }: RoomDialogProps) => {
const currentRoom = useRoomStore((state) => state.currentRoom);

useEffect(() => {
if (currentRoom?.roomId) {
if (currentRoom) {
navigate(`/game/${currentRoom.roomId}`);
onOpenChange(false);
signalingSocket.joinRoom(currentRoom);
resetAndClose();
}
}, [currentRoom]);
}, [currentRoom, navigate]);

const resetAndClose = () => {
setRoomName('');
Expand All @@ -44,6 +45,7 @@ const RoomDialog = ({ open, onOpenChange }: RoomDialogProps) => {
setIsLoading(true);
gameSocket.connect();
signalingSocket.connect();

gameSocket.createRoom(roomName.trim(), hostNickname.trim());
} catch (error) {
console.error('방 생성 실패:', error);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { gameSocket } from '@/services/gameSocket';
import { signalingSocket } from '@/services/signalingSocket';
import { getRoomsQuery } from '@/stores/queries/getRoomsQuery';
import useRoomStore from '@/stores/zustand/useRoomStore';
import { RoomDialogProps } from '@/types/roomTypes';
import { useEffect, useState } from 'react';
Expand All @@ -24,13 +25,9 @@ const JoinDialog = ({ open, onOpenChange, roomId }: JoinDialogProps) => {
const [playerNickname, setPlayerNickname] = useState('');
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const { currentRoom } = useRoomStore.getState();

useEffect(() => {
if (currentRoom?.roomId) {
navigate(`/game/${currentRoom.roomId}`);
}
}, [currentRoom?.roomId, navigate]);
const { data: rooms } = getRoomsQuery();
const currentRoom = rooms.find((room) => room.roomId === roomId);
const { setCurrentRoom } = useRoomStore.getState();

const resetAndClose = () => {
setPlayerNickname('');
Expand All @@ -45,9 +42,12 @@ const JoinDialog = ({ open, onOpenChange, roomId }: JoinDialogProps) => {
setIsLoading(true);
gameSocket.connect();
signalingSocket.connect();

setCurrentRoom(currentRoom);
gameSocket.joinRoom(roomId, playerNickname.trim());
await signalingSocket.joinRoom(currentRoom);

onOpenChange(false);
resetAndClose();
navigate(`/game/${roomId}`);
} catch (error) {
console.error('방 입장 실패:', error);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import SearchBar from '@/components/common/SearchBar';
import RoomHeader from './RoomHeader/RoomHeader';
import RoomList from './RoomList/RoomList';
import { gameSocket } from '@/services/gameSocket';
import { useEffect } from 'react';
import { signalingSocket } from '@/services/signalingSocket';
import { useRefreshRooms } from '@/hooks/useRefreshRooms';

const RoomPage = () => {
const refreshRooms = useRefreshRooms();
const refetchRooms = useRefreshRooms();

useEffect(() => {
refreshRooms();
refetchRooms();

const interval = setInterval(() => {
refreshRooms();
}, 3000);
refetchRooms();
}, 3000); // 3초에 한 번씩

return () => clearInterval(interval);
}, [refreshRooms]);
return () => {
clearInterval(interval);
};
}, [refetchRooms]);

return (
<div>
Expand Down
6 changes: 2 additions & 4 deletions fe/src/services/SocketService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ export class SocketService {
this.#socket = socket;
}

validateSocket() {
if (!this.#socket) {
throw new Error('Socket connection not established');
}
isConnected() {
return !this.#socket?.connected;
}

disconnect() {
Expand Down
Loading

0 comments on commit 083c5a5

Please sign in to comment.