diff --git a/frontend/src/components/Common/Loading.tsx b/frontend/src/components/Common/Loading.tsx index cb74d11..a0b3639 100644 --- a/frontend/src/components/Common/Loading.tsx +++ b/frontend/src/components/Common/Loading.tsx @@ -17,9 +17,9 @@ export default function Loading({ size, color }: Props) { cy="50" fill="none" stroke={color} - stroke-width="10" + strokeWidth="10" r="35" - stroke-dasharray="164.93361431346415 56.97787143782138" + strokeDasharray="164.93361431346415 56.97787143782138" > void; } export default function SocketTimer(props: Props) { - let { socket, endsAt, isConnected, onTimeout } = props; - // api 연결이 X endsAt 대신 임시로 만들어놓은 것. - // min 1 => 60초 동안 돌아갑니다. 변경해서 쓰세요 일단은.. + let { socket, endsAt, isConnected, onTimeout, pingTime, socketEvent } = props; + // 대회 시간 검증이 안 되어 있어서, 끝나는 시간이 현재 시간보다 모두 전입니다. 그래서 지금 시간 기준으로 120분 더하고 마지막 시간이다라고 가정합니다. const min = 120; endsAt = new Date(new Date().getTime() + min * 60 * 1000); const { remainMiliSeconds, isTimeout } = useSocketTimer({ socket, endsAt, - socketEvent: 'ping', + socketEvent, + pingTime, }); useEffect(() => { diff --git a/frontend/src/hooks/timer/useSocketTimer.ts b/frontend/src/hooks/timer/useSocketTimer.ts index 3d25bdc..33f891e 100644 --- a/frontend/src/hooks/timer/useSocketTimer.ts +++ b/frontend/src/hooks/timer/useSocketTimer.ts @@ -6,47 +6,44 @@ interface Props { socket: Socket; endsAt: Date; socketEvent: string; + pingTime: number; } -export default function useSocketTimer({ socket, endsAt, socketEvent }: Props) { +export default function useSocketTimer({ socket, endsAt, socketEvent, pingTime }: Props) { const timerIntervalId = useRef(null); + const pingIntervalId = useRef(null); + const endTime = useMemo(() => endsAt.getTime(), [endsAt]); const [isTimeout, setIsTimeout] = useState(false); const [remainMiliSeconds, setRemainMiliSeconds] = useState(-1); useEffect(() => { - console.log('타이머 실행'); - // 웹 소켓 대신 사용. - mockWebSocket(); + if (pingIntervalId.current) clearInterval(pingIntervalId.current); + socket.emit(socketEvent); - if (socket.hasListeners(socketEvent)) { - socket.on(socketEvent, handlePingMessage); - } + socket.on(socketEvent, handlePingMessage); + + pingIntervalId.current = setInterval(() => { + socket.emit(socketEvent); + }, pingTime); }, [socket]); - const handlePingMessage = useCallback((time: Date | string) => { - console.log(time); - if (timerIntervalId.current) clearInterval(timerIntervalId.current); - - time = typeof time === 'string' ? new Date(time) : time; - const remainMiliSec = endTime - time.getTime(); - setRemainMiliSeconds(remainMiliSec); - timerIntervalId.current = setInterval(() => { - setRemainMiliSeconds((prev) => prev - 1000); - }, 1000); - }, []); - - // 웹 소켓 대신 사용. - // 웹 소켓 연결 후 삭제 예정 - const mockWebSocket = useCallback(() => { - const delayFactor = 2000; - const serverTime = new Date(); - handlePingMessage(serverTime); - setInterval(() => { - const serverTime = new Date(); - handlePingMessage(serverTime); - }, 5000 + Math.random() * delayFactor); - }, []); + const handlePingMessage = useCallback( + (time: Date) => { + console.log('서버에서 온 시간 websocket 연결 확인 용', time); + if (timerIntervalId.current) clearInterval(timerIntervalId.current); + + time = typeof time === 'string' ? new Date(time) : time; + + const remainMiliSec = endTime - time.getTime(); + setRemainMiliSeconds(remainMiliSec); + + timerIntervalId.current = setInterval(() => { + setRemainMiliSeconds((prev) => prev - 1000); + }, 1000); + }, + [endTime], + ); useEffect(() => { // 초기 값인 -1 => 서버에서 시간이 오지 않았다. @@ -55,5 +52,6 @@ export default function useSocketTimer({ socket, endsAt, socketEvent }: Props) { setIsTimeout(true); } }, [remainMiliSeconds]); + return { remainMiliSeconds, isTimeout }; } diff --git a/frontend/src/pages/ContestPage.tsx b/frontend/src/pages/ContestPage.tsx index 2bf1fa0..8afdda7 100644 --- a/frontend/src/pages/ContestPage.tsx +++ b/frontend/src/pages/ContestPage.tsx @@ -24,6 +24,8 @@ import { isNil } from '@/utils/type'; const RUN_SIMULATION = '테스트 실행'; const CANCEL_SIMULATION = '실행 취소'; const DASHBOARD_URL = '/contest/dashboard'; +const COMPEITION_PING_TIME = 5 * 1000; +const COMPEITION_SOCKET_EVENT = 'ping'; export default function ContestPage() { const { id } = useParams<{ id: string }>(); @@ -107,6 +109,8 @@ export default function ContestPage() { socket={socket.current} isConnected={isConnected} endsAt={new Date(endsAt)} + pingTime={COMPEITION_PING_TIME} + socketEvent={COMPEITION_SOCKET_EVENT} onTimeout={handleTimeout} />