-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: 실시간 채팅 기능 구현 #81
The head ref may contain hidden characters: "feat#14/\uC2E4\uC2DC\uAC04-\uCC44\uD305-\uAE30\uB2A5-\uAD6C\uD604"
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오래 걸렸다고 말씀하셨지만 처음 구현해보신 건데도 이 정도면 엄청 빠르게 하신 거라고 생각합니다..!! 저도 웹소켓 사용하는 로직은 구현해본 적이 없어서 리뷰가 도움이 될 수 있을지 모르겠는데 열심히 해보겠습니다.. 😂😂 정말 고생 많으셨습니다!! 😁👍👍
@@ -12,6 +12,7 @@ | |||
"dependencies": { | |||
"@hookform/resolvers": "^3.9.1", | |||
"@react-oauth/google": "^0.12.1", | |||
"@stomp/stompjs": "^7.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
socket.io
만 생각했는데 요런 가벼운 라이브러리도 있었군요..!! 하나 알아갑니다 👍
src/components/chat/MessageInput.tsx
Outdated
const toggleMenu = () => { | ||
setShowMenu(!showMenu); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요 부분은 showMenu
를 통해 렌더링을 제어하는 로직인 것 같은데 상태값을 직접 참조하는게 (prev
) 더 안정적일 것 같습니다!!
사용자가 여러 번 동시에 누른다거나 (그럴 일이 없었으면 하는데..) 하면 비동기 로직 특성 상 변경되기 전에 값을 읽어와 버리는 문제가 생길 수도 있을 것 같아요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아항 그렇겟네요... 그럼
setShowMenu((prev) => !prev);
이런식으로 수정하는게 좋을 것 같다는 말씀이시죠??
import { useState, useEffect, useRef } from 'react'; | ||
import { getChatMessages } from './getChatMessages'; | ||
|
||
const useWebSocket = (roomId: number | null) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
api
폴더는 보통 종속되지 않는 순수 함수만 포함하는게 일반적이라 useState
같은 리액트 훅을 사용하다 보니 아예 hooks
폴더로 이동시키는 것도 괜찮을 것 같네요!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아항! 폴더를 어떻게 구분해야할지 너무 헷갈리네요,, 감사합니당!!😆
const [messages, setMessages] = useState<ChatMessagesFromServerFull | null>( | ||
null, | ||
); | ||
const subscribed = useRef(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서 위의 isSubscribed
상태값과 여기 subscribed
변수는 둘 다 구독 여부를 확인하기 위한 값으로 보이는데 용도가 같아서 중복되는 것 같습니다!! 아니면 혹시 구독 여부 변경 시 리렌더링이 필요하지 않은 상황이 추가적으로 필요한 건가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
흐억 중복 맞아요... 제가 useState
랑 useRef
랑 두개 다 해보고 하나 지우려고 했었는데 깜빡했었네요 수정하겠습니당!
|
||
useEffect(() => { | ||
const connectWebSocket = () => { | ||
const ws = new WebSocket(`${import.meta.env.VITE_API_BASE_URL}/ws`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
한줄씩 읽어 실행시키는 언어 특성 상 const
키워드로 한번 환경 변수를 확정하고 사용하는게 조금 더 안전할 것 같습니다!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아하 먼저 첫줄에 환경변수 확정하고 불러오는 형태로 수정하겠습니다!!
const receivedMessage: SubscribeServer = JSON.parse(message.body); | ||
console.log('구독 새로운 메시지 수신:', receivedMessage); | ||
|
||
switch (receivedMessage.messageType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이게 말씀하신 switch
문이네요 😁 이 부분을 메세지 상태 제어 로직으로 활용할 수도 있을 것 같은데 (메세지 로드나 전송 실패 시 핸들링 같은 느낌으로요!!) 혹시 개발 완료 하고 제거하시면 따로 추가하시거나 아니면 해당 부분이 필요없다고 느끼신걸까요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 백엔드 측에서 messageType
이 READ
일 경우에만 보내주신다고 하셔서 READ
일때를 상태 제어 로직으로 활용하면 좋을 것 같네요!
subscribed.current = false; | ||
} | ||
}; | ||
}, [roomId, stompClient, setIsSubscribed]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 살짝 단순히 궁금해서 여쭤보는 건데 의존성 배열에 있는 stompClient
와 setIsSubscribed
값은 채팅방을 들어와서 useEffect
가 실행된 후에 채팅방을 나가기 전까진 변경될 일이 없을 것 같아서 의존성에서 제외해도 될 것 같은데 에러가 발생하는 경우 구독 해제를 감안해서 추가하신 건가요?? 근데 린트가 추가하라고 하면 추가하는게 맞긴합니다.. 😂😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 setIsSubscribed
요 부분을 messageInput.tsx
에서 사용했었어서 넣었다가 방금 삭제했습니당... 그리구 stompClient
는 린트가 추가하라고 해서 추가했습니당.. ㅋㅋㅋㅋㅋㅋ
|
||
try { | ||
const res = await axios.get( | ||
`${import.meta.env.VITE_API_BASE_URL}/api/chat/${roomId}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요 부분도 동일합니다! 😊
src/types/chat.d.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
타입 정의가 진짜 빡세네요... 😂 고생 많으셨어요..!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
감사합니당 😂😂!!
1. 무슨 이유로 코드를 변경했나요?
2. 어떤 위험이나 장애를 발견했나요?
3. 관련 스크린샷을 첨부해주세요.
4. 완료 사항
웹소켓 연결, 구독, 해제, 전체 메시지 api 조회까지 연결해두었습니다.
5. 추가 사항
메시지 send 보내는 로직을 조금 구현해두긴 했는데 제가 MessageInput에서
useWebSocket
을 한 번 더 부르도록 구현을 했더니 웹소켓 연결이 두번 가서 일단 현재는 주석처리 해두었고 코드가 너무 길어질 것 같아서 다음 이슈에서 수정하도록 하겠습니다!그리고 현재 가치택시 서버에 로그가 너무 많이 찍히는? 백엔드 이슈가 있는 것 같아서 채팅 백엔드 담당자분 서버로 연결해서 구현해보느라
header
에'ngrok-skip-browser-warning': '69420',
가 들어갔는데 나중에 가치택시 서버로 연결할땐 제거할 예정입니다!src/libs/apis/chat/connectWebSocket.api.ts
이 부분에서 지금 코드가 너무 긴데subscribe
했을때 오는 메시지 개발하면서 확인해본다고 저렇게 두었는데 저switch
부분 전체는 개발 완료된 후에 아예 제거할 예정입니다..다음이슈에서 메시지 조회 무한 스크롤 구현, 메시지 send, 퇴장 처리까지 구현하도록 하겠습니다. 웹소켓 연결을 처음 해봐서 꽤 오래 걸렸네요,,😅 남은 api 연결은 최대한 빠르게 해보겠습니다!