From 5df76c57c213a92a1dd171751d431503962db14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=EC=A7=80=EC=9C=A4?= <70828192+cheonjiyun@users.noreply.github.com> Date: Sun, 15 Dec 2024 22:36:03 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20=EA=B8=80=EC=94=A8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Night.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/Night.tsx b/src/pages/Night.tsx index 7aa2c68..e033b59 100644 --- a/src/pages/Night.tsx +++ b/src/pages/Night.tsx @@ -39,7 +39,6 @@ export default function Night({ statusType, publishSkill, mafiaSkillPlayer }: Pr ) : (
- {myJob} <> {'MAFIA' === myJob && ( Date: Sun, 15 Dec 2024 22:36:22 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A7=81=EC=97=85=20=EC=B0=BE=EC=95=84=EC=84=9C=20?= =?UTF-8?q?=EB=B3=B4=EC=97=AC=EC=A3=BC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/chat/ChatGroup.tsx | 7 ++++++- src/util/job.ts | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 src/util/job.ts diff --git a/src/components/chat/ChatGroup.tsx b/src/components/chat/ChatGroup.tsx index 47fc9e4..bdb21d7 100644 --- a/src/components/chat/ChatGroup.tsx +++ b/src/components/chat/ChatGroup.tsx @@ -1,9 +1,12 @@ /** @jsxImportSource @emotion/react */ import { css } from '@emotion/react'; import { forwardRef } from 'react'; +import { useRecoilState } from 'recoil'; +import { roomInfoState } from '../../recoil/roominfo/atom'; import { VariablesCSS } from '../../styles/VariablesCSS'; import { Chat } from '../../type'; +import { getPlayerJob } from '../../util/job'; import PlayerChat from '../player/PlayerChat'; import ChatMessage from './ChatMessage'; @@ -15,9 +18,11 @@ interface PropsType { export default forwardRef(function ChatGroup(props: PropsType, ref: any) { const { chats } = props; + const [roomInfo] = useRecoilState(roomInfoState); + return (
- +

{chats[0].name}

{chats.map((chat, idx) => ( diff --git a/src/util/job.ts b/src/util/job.ts new file mode 100644 index 0000000..4d24d35 --- /dev/null +++ b/src/util/job.ts @@ -0,0 +1,5 @@ +import { Job, Player } from '../type'; + +export const getPlayerJob = (players: Player[], name: string): Job => { + return players.find(el => el.name == name)?.job || null; +}; From 7ddd936bb9eb7a35a6303bcd2f72224943a5e879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=EC=A7=80=EC=9C=A4?= <70828192+cheonjiyun@users.noreply.github.com> Date: Thu, 26 Dec 2024 15:22:50 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20SSE=EC=99=80=20=EC=9B=B9?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20URL=EC=9D=84=20=ED=95=9C=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EC=97=90=EC=84=9C=20=EA=B4=80=EB=A6=AC=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Game.tsx | 26 +++++++++++++++----------- src/socket/url.ts | 10 ++++++++++ src/sse/url.ts | 3 +++ 3 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/socket/url.ts create mode 100644 src/sse/url.ts diff --git a/src/pages/Game.tsx b/src/pages/Game.tsx index 113e6b2..fd02911 100644 --- a/src/pages/Game.tsx +++ b/src/pages/Game.tsx @@ -4,8 +4,9 @@ import { useEffect, useRef, useState } from 'react'; import { useRecoilState, useSetRecoilState } from 'recoil'; import { getChats, getGamesInfo, getMyJob } from '../axios/http'; -import { BASE_URL, DOMAIN } from '../axios/instances'; import { gameRound, myJobState, roomInfoState } from '../recoil/roominfo/atom'; +import { BORKER_URL, CHAT_PUB, CHAT_SUB, JOB_SKILL_SUB } from '../socket/url'; +import { EVENTSOURCE_URL } from '../sse/url'; import { ChatArray, ChatResponse, GameStatus, SkillResponse, WaitingRoomInfo } from '../type'; import Day from './Day'; import Night from './Night'; @@ -20,7 +21,6 @@ export default function Game() { const [chatSubscribeId, setChatSubscribeId] = useState(null); const [skillSubscribeId, setSkillSubscribeId] = useState(null); const [mafiaSkillPlayer, setMafiaSkillPlayer] = useState(null); - const [roomsInfoState, setRoomsInfoState] = useRecoilState(roomInfoState); // 방 정보 const [waitingRoomInfoState, setWaitingRoomInfoState] = useState({ totalPlayers: 1, isMaster: true, @@ -34,6 +34,7 @@ export default function Game() { const [finishSocketConneted, setFinishSocketConnetd] = useState(false); // 웹 소켓 연결이 끝난다는 트리거(채팅 구독이 연결 전에 실행될 때를 대비해 다시 실행하기 위함) const setGameRoundState = useSetRecoilState(gameRound); + const [roomsInfoState, setRoomsInfoState] = useRecoilState(roomInfoState); // 방 정보 // 방 상태 불러오기 const [gamesStatus, setGameStatus] = useState({ statusType: 'WAIT' }); @@ -47,7 +48,7 @@ export default function Game() { const EventSource = EventSourcePolyfill; - eventSource.current = new EventSource(`${BASE_URL}/games/subscribe`, { + eventSource.current = new EventSource(EVENTSOURCE_URL, { headers: { Authorization: `Basic ${auth}` }, heartbeatTimeout: 1000 * 60 * 60 * 12, withCredentials: true, @@ -69,7 +70,7 @@ export default function Game() { // WebSocket const connect = () => { const socket = new StompJs.Client({ - brokerURL: `wss://${DOMAIN}/api/stomp`, + brokerURL: BORKER_URL, reconnectDelay: 10000, }); @@ -97,7 +98,7 @@ export default function Game() { // 채팅구독함수 const subscribeChat = () => { if (!socketClientState.current?.connected) return; - const chatSubscribeId = socketClientState.current.subscribe(`/sub/chat/${auth}`, response => { + const chatSubscribeId = socketClientState.current.subscribe(CHAT_SUB(auth), response => { const msg: ChatResponse = JSON.parse(response.body); const isOwner = msg.name == roomsInfoState.myName; @@ -118,7 +119,7 @@ export default function Game() { if (!socketClientState.current?.connected) return; socketClientState.current.publish({ - destination: `/pub/chat/${auth}`, + destination: CHAT_PUB(auth), body: JSON.stringify({ content: content }), }); }; @@ -143,10 +144,13 @@ export default function Game() { const subscribeSkill = async () => { if (!socketClientState.current?.connected) return; - const mafiaSubscribeId = socketClientState.current.subscribe(`/sub/mafia/${auth}`, response => { - const msg: SkillResponse = JSON.parse(response.body); - setMafiaSkillPlayer(msg.content); - }); + const mafiaSubscribeId = socketClientState.current.subscribe( + JOB_SKILL_SUB(auth, myJobRecoilState), + response => { + const msg: SkillResponse = JSON.parse(response.body); + setMafiaSkillPlayer(msg.content); + }, + ); setSkillSubscribeId(mafiaSubscribeId); }; @@ -173,7 +177,7 @@ export default function Game() { subscribeSkill(); return () => unsubscribeSkill(); - }, [gamesStatus.statusType, finishSocketConneted]); + }, [gamesStatus.statusType, finishSocketConneted, myJobRecoilState]); // 방 정보 저장 (방 상태가 바뀔때만 작동?) useEffect(() => { diff --git a/src/socket/url.ts b/src/socket/url.ts new file mode 100644 index 0000000..bd9cb2b --- /dev/null +++ b/src/socket/url.ts @@ -0,0 +1,10 @@ +import { DOMAIN } from '../axios/instances'; +import { Job } from '../type'; + +export const BORKER_URL = `wss://${DOMAIN}/api/stomp`; +export const CHAT_SUB = (auth: string | null) => `/sub/chat/${auth}`; +export const CHAT_PUB = (auth: string | null) => `/pub/chat/${auth}`; + +export const JOB_SKILL_SUB = (auth: string | null, job: Job) => + `/sub/job/skill/${job?.toLocaleLowerCase()}/${auth}`; +export const JOB_SKILL_PUB = (auth: string | null) => `/pub/skill/${auth}`; diff --git a/src/sse/url.ts b/src/sse/url.ts new file mode 100644 index 0000000..5b05806 --- /dev/null +++ b/src/sse/url.ts @@ -0,0 +1,3 @@ +import { BASE_URL } from '../axios/instances'; + +export const EVENTSOURCE_URL = `${BASE_URL}/games/subscribe`; From bff7330ac29526b8a86c1e70122486c1e0fc7c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=EC=A7=80=EC=9C=A4?= <70828192+cheonjiyun@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:30:02 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20=EC=B4=88=EB=8C=80=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EB=B0=A4=20?= =?UTF-8?q?=EB=A7=88=ED=94=BC=EC=95=84=20url=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constant/localStroge.ts | 1 + src/pages/Game.tsx | 13 +++++++------ src/pages/InputName.tsx | 7 +++++++ src/socket/url.ts | 11 ++++++++--- 4 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 src/constant/localStroge.ts diff --git a/src/constant/localStroge.ts b/src/constant/localStroge.ts new file mode 100644 index 0000000..a90398d --- /dev/null +++ b/src/constant/localStroge.ts @@ -0,0 +1 @@ +export const CODE = 'code'; diff --git a/src/pages/Game.tsx b/src/pages/Game.tsx index fd02911..5e1b882 100644 --- a/src/pages/Game.tsx +++ b/src/pages/Game.tsx @@ -4,8 +4,9 @@ import { useEffect, useRef, useState } from 'react'; import { useRecoilState, useSetRecoilState } from 'recoil'; import { getChats, getGamesInfo, getMyJob } from '../axios/http'; +import { CODE } from '../constant/localStroge'; import { gameRound, myJobState, roomInfoState } from '../recoil/roominfo/atom'; -import { BORKER_URL, CHAT_PUB, CHAT_SUB, JOB_SKILL_SUB } from '../socket/url'; +import { BORKER_URL, CHAT_PUB, CHAT_SUB, JOB_SKILL_PUB, JOB_SKILL_SUB } from '../socket/url'; import { EVENTSOURCE_URL } from '../sse/url'; import { ChatArray, ChatResponse, GameStatus, SkillResponse, WaitingRoomInfo } from '../type'; import Day from './Day'; @@ -143,12 +144,13 @@ export default function Game() { // 밤 직업구독 함수 const subscribeSkill = async () => { if (!socketClientState.current?.connected) return; + const code = localStorage.getItem(CODE); const mafiaSubscribeId = socketClientState.current.subscribe( - JOB_SKILL_SUB(auth, myJobRecoilState), + JOB_SKILL_SUB(code, myJobRecoilState), response => { const msg: SkillResponse = JSON.parse(response.body); - setMafiaSkillPlayer(msg.content); + setMafiaSkillPlayer(msg.result); }, ); @@ -166,8 +168,9 @@ export default function Game() { if (!socketClientState.current?.connected) return; socketClientState.current.publish({ - destination: `/pub/skill/${auth}`, + destination: JOB_SKILL_PUB, body: JSON.stringify({ target: name }), + headers: { Authorization: `Basic ${auth}` }, }); }; @@ -200,8 +203,6 @@ export default function Game() { // 내 직업 if (gamesStatus.statusType !== 'WAIT' && !myJobRecoilState) { const myJobResponse = await getMyJob(); - console.log(myJobResponse); - setMyJobRecoilState(myJobResponse.job); } })(); diff --git a/src/pages/InputName.tsx b/src/pages/InputName.tsx index a54097f..b777eae 100644 --- a/src/pages/InputName.tsx +++ b/src/pages/InputName.tsx @@ -9,6 +9,7 @@ import BottomButton from '../components/button/BottomButton'; import AppContainerCSS from '../components/layout/AppContainerCSS'; import { notifyUseToast } from '../components/toast/NotifyToast'; import TopEnter from '../components/top/TopEnter'; +import { CODE } from '../constant/localStroge'; import { VariablesCSS } from '../styles/VariablesCSS'; export default function InputName() { @@ -33,8 +34,14 @@ export default function InputName() { if (canParticipateRoom()) { try { + // auth저장 const auth = await participateRooms({ code: code, name: name }); localStorage.setItem('auth', auth.auth); + + // 코드저장 + const codeParams = !searchParams.get('code') ? '' : searchParams.get('code'); + localStorage.setItem(CODE, codeParams?.toString() || ''); + navigate('/game'); // eslint-disable-next-line } catch (error: any) { diff --git a/src/socket/url.ts b/src/socket/url.ts index bd9cb2b..47778a9 100644 --- a/src/socket/url.ts +++ b/src/socket/url.ts @@ -1,10 +1,15 @@ import { DOMAIN } from '../axios/instances'; import { Job } from '../type'; +// *연결* export const BORKER_URL = `wss://${DOMAIN}/api/stomp`; + +// *채팅* +// chat export const CHAT_SUB = (auth: string | null) => `/sub/chat/${auth}`; export const CHAT_PUB = (auth: string | null) => `/pub/chat/${auth}`; -export const JOB_SKILL_SUB = (auth: string | null, job: Job) => - `/sub/job/skill/${job?.toLocaleLowerCase()}/${auth}`; -export const JOB_SKILL_PUB = (auth: string | null) => `/pub/skill/${auth}`; +// skill +export const JOB_SKILL_SUB = (code: string | null, job: Job) => + `/sub/jobs/skill/${job?.toLocaleLowerCase()}/${code}`; +export const JOB_SKILL_PUB = `/pub/jobs/skill`;