Skip to content
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

Merged
merged 44 commits into from
Jan 25, 2025

Conversation

woneeeee
Copy link
Collaborator

@woneeeee woneeeee commented Jan 24, 2025

1. 무슨 이유로 코드를 변경했나요?


2. 어떤 위험이나 장애를 발견했나요?


3. 관련 스크린샷을 첨부해주세요.

image

4. 완료 사항

웹소켓 연결, 구독, 해제, 전체 메시지 api 조회까지 연결해두었습니다.

5. 추가 사항

메시지 send 보내는 로직을 조금 구현해두긴 했는데 제가 MessageInput에서 useWebSocket을 한 번 더 부르도록 구현을 했더니 웹소켓 연결이 두번 가서 일단 현재는 주석처리 해두었고 코드가 너무 길어질 것 같아서 다음 이슈에서 수정하도록 하겠습니다!
그리고 현재 가치택시 서버에 로그가 너무 많이 찍히는? 백엔드 이슈가 있는 것 같아서 채팅 백엔드 담당자분 서버로 연결해서 구현해보느라 header'ngrok-skip-browser-warning': '69420',가 들어갔는데 나중에 가치택시 서버로 연결할땐 제거할 예정입니다!
src/libs/apis/chat/connectWebSocket.api.ts이 부분에서 지금 코드가 너무 긴데 subscribe했을때 오는 메시지 개발하면서 확인해본다고 저렇게 두었는데 저 switch 부분 전체는 개발 완료된 후에 아예 제거할 예정입니다..

다음이슈에서 메시지 조회 무한 스크롤 구현, 메시지 send, 퇴장 처리까지 구현하도록 하겠습니다. 웹소켓 연결을 처음 해봐서 꽤 오래 걸렸네요,,😅 남은 api 연결은 최대한 빠르게 해보겠습니다!

@woneeeee woneeeee added the feat 신규피쳐 label Jan 24, 2025
@woneeeee woneeeee requested a review from WooGi1020 January 24, 2025 15:28
@woneeeee woneeeee self-assigned this Jan 24, 2025
@woneeeee woneeeee linked an issue Jan 24, 2025 that may be closed by this pull request
Copy link

구현 기능 확인하기: https://gachtaxi-m6sd5wg0j-cogis-projects.vercel.app

Copy link
Collaborator

@WooGi1020 WooGi1020 left a 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",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

socket.io 만 생각했는데 요런 가벼운 라이브러리도 있었군요..!! 하나 알아갑니다 👍

Comment on lines 17 to 19
const toggleMenu = () => {
setShowMenu(!showMenu);
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 부분은 showMenu 를 통해 렌더링을 제어하는 로직인 것 같은데 상태값을 직접 참조하는게 (prev) 더 안정적일 것 같습니다!!
사용자가 여러 번 동시에 누른다거나 (그럴 일이 없었으면 하는데..) 하면 비동기 로직 특성 상 변경되기 전에 값을 읽어와 버리는 문제가 생길 수도 있을 것 같아요!

Copy link
Collaborator Author

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) => {
Copy link
Collaborator

@WooGi1020 WooGi1020 Jan 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api폴더는 보통 종속되지 않는 순수 함수만 포함하는게 일반적이라 useState 같은 리액트 훅을 사용하다 보니 아예 hooks 폴더로 이동시키는 것도 괜찮을 것 같네요!!

Copy link
Collaborator Author

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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 위의 isSubscribed 상태값과 여기 subscribed 변수는 둘 다 구독 여부를 확인하기 위한 값으로 보이는데 용도가 같아서 중복되는 것 같습니다!! 아니면 혹시 구독 여부 변경 시 리렌더링이 필요하지 않은 상황이 추가적으로 필요한 건가요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흐억 중복 맞아요... 제가 useStateuseRef랑 두개 다 해보고 하나 지우려고 했었는데 깜빡했었네요 수정하겠습니당!


useEffect(() => {
const connectWebSocket = () => {
const ws = new WebSocket(`${import.meta.env.VITE_API_BASE_URL}/ws`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

한줄씩 읽어 실행시키는 언어 특성 상 const 키워드로 한번 환경 변수를 확정하고 사용하는게 조금 더 안전할 것 같습니다!!

Copy link
Collaborator Author

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) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이게 말씀하신 switch 문이네요 😁 이 부분을 메세지 상태 제어 로직으로 활용할 수도 있을 것 같은데 (메세지 로드나 전송 실패 시 핸들링 같은 느낌으로요!!) 혹시 개발 완료 하고 제거하시면 따로 추가하시거나 아니면 해당 부분이 필요없다고 느끼신걸까요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 백엔드 측에서 messageTypeREAD일 경우에만 보내주신다고 하셔서 READ일때를 상태 제어 로직으로 활용하면 좋을 것 같네요!

subscribed.current = false;
}
};
}, [roomId, stompClient, setIsSubscribed]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 살짝 단순히 궁금해서 여쭤보는 건데 의존성 배열에 있는 stompClientsetIsSubscribed 값은 채팅방을 들어와서 useEffect 가 실행된 후에 채팅방을 나가기 전까진 변경될 일이 없을 것 같아서 의존성에서 제외해도 될 것 같은데 에러가 발생하는 경우 구독 해제를 감안해서 추가하신 건가요?? 근데 린트가 추가하라고 하면 추가하는게 맞긴합니다.. 😂😂

Copy link
Collaborator Author

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}`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요 부분도 동일합니다! 😊

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

타입 정의가 진짜 빡세네요... 😂 고생 많으셨어요..!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니당 😂😂!!

Copy link

구현 기능 확인하기: https://gachtaxi-qm0j08ce3-cogis-projects.vercel.app

@woneeeee woneeeee merged commit 4bb224f into main Jan 25, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat 신규피쳐
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: 실시간 채팅 기능 구현
2 participants