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

채팅 기능 #76

Open
wants to merge 32 commits into
base: develop
Choose a base branch
from
Open

채팅 기능 #76

wants to merge 32 commits into from

Conversation

JunBe
Copy link
Member

@JunBe JunBe commented Feb 14, 2025

#️⃣ Issue Number

#71

📝 작업 설명

WebSocket, STOMP를 활용하여 구현하였습니다.

현재 채팅방 생성/조회 , 메시지 전송/조회 구현되어 있습니다.

구독 기능은 @sendto를 사용하여 WebSocket을 구독한 사용자에게 메시지를 보내는 방식이나, 앱 재시작 시 프론트엔드에서 구독 목록을 다시 불러와 처리하는 것이 현재 어려워 다른 방식으로 처리했습니다.
대안으로 구독 목록을 DB에 저장하여 DB에 있는 구독자들에게 전체 메시지가 전송될 수 있도록 하여 한 번 구독을 하면 메세지를 받을 수 있도록 구현했습니다.

Postman에서는 WebSocket의 연결 여부 밖에 테스트가 불가능하여 WebSocket, STOMP 관련 테스트는 아래 사이트에서 테스트가 가능합니다.
https://min9805.github.io/stomp/

📸스크린샷 (선택)

💬 리뷰 요구사항

리뷰어가 중점적으로 봐줬으면 좋겠는 부분이 있으면 적어주세요.
논의해야할 부분이 있다면 적어주세요.
ex) 메서드 XXX의 이름을 더 잘 짓고 싶은데 혹시 좋은 명칭이 있을까요?

✅ PR Checklist

PR이 다음 요구 사항을 충족하는지 확인하세요.

  • 커밋 메시지 컨벤션에 맞게 작성했습니다.
  • 변경 사항에 대한 테스트를 했습니다.(버그 수정/기능에 대한 테스트).

JunBe added 19 commits February 13, 2025 15:05
- WebSocket 의존성 추가

Resolves: #71
- WebSocketConfig
 - STOMP WebSocket 엔드포인트 "/ws" 설정
 - 메시지 전송 시 엔드포인트 "/app" prefix 설정
 - 메시지 받을 시 엔드포인트 "/topic" prefix 설정

- PathConst
 - 로그인 없이 접근 가능하도록 웹 소켓 관련 경로 임시 허용

Resolves: #71
- /api/chat/room 엔드포인트로 채팅방을 생성
 - 채팅방은 상품 id, 판매자 id, 구매자 id를 조합하여 구분
- /api/chat/room/{userId} 엔드포인트로 채팅방 조회
 - {userId}에 해당하는 구매자, 판매자의 채팅방을 전부 조회

Resolves: #71
- ChatMessageController
 - @MessageMapping을 통해 해당 엔드포인트에 메시지 전송 후 로직 처리
 - @sendto를 통해 해당 엔트포인트를 구독하고 있는 사용자에게 처리된 메시지 전송

- ChatMessageService
 - 방 번호, 유저 id null 여부 검사 후 예외 처리
 - ChatMessageRequest를 통해 받은 메시지 정보 DB에 저장

Resolves: #71
- 기존 ChatRoom 데이터를 전부 반환하던 로직을 ChatRoomResponse DTO를 생성하여 필요한 정보만 반환하도록 변경

Resolves: #71
- WebSocket 관련 메시지 Controller ChatMessageWebSocketController로 이름 변경
- Rest API 구현 메시지 Controller는 ChatMessageController에 구현

Resolves: #71
- roomId를 통해 채팅방의 전체 메시지를 조회
- 기본으로 10개의 메시지가 조회되고, 첫 페이지 로드
- 메시지는 최신순으로 조회

Resolves: #71
- 공통으로 `/api/chat/room`를 사용하도록 변경

Resolves: #71
- 특정 유저가 속해 있는 채팅방 조회시 반환되는 최신 메시지 필드에 오래된 메시지가 반환되어 최신 메시지 반환하도록 수정

Resolves: #71
- ChatRoom의 전체 데이터가 응답으로 반환되어 ChatRoomResponse DTO를 사용하여 필요한 값만 반환하도록 변경

Resolves: #71
- Product, User 객체를 받는 필드 productId -> product, buyerId -> buyer, sellerId -> seller로 변경

- 필드명에 맞춰 Repository 수정

Resolves: #71
- 중복되는 로직을 chatRoomResponseEntity 메서드로 만들어 각 가능에서 메서드를 사용하도록 변경

Resolves: #71
- 구독자 관리용 Entity 생성
- 채팅방 생성시 판매자, 구매자는 해당 채팅방을 자동으로 구독

Resolves: #71
- @sendto는 현재 구독중인 유저에게만 메시지 전송
- 앱 재시작 시 구독중인 유저 상태가 모두 해제되어 DB에 저장되어 있는 구독자에게 모두 메시지 전송하도록 구현

Resolves: #71
- ResponseEntity와 ApiResponse를 사용하여 응답 값을 반환하도록 변경

Resolves: #71
@JunBe JunBe self-assigned this Feb 14, 2025
@JunBe JunBe linked an issue Feb 14, 2025 that may be closed by this pull request
11 tasks
- ChatFile 엔티티 생성
- 파일 전송시 해당 데이터들을 관리

Resolves: #71
- Request
 - 전송자 ID, 파일 URL

- Response
 - 방 번호, 프리사인 URL, 파일 타입

Resolves: #71
- 파일 전송 엔드포인트 `/chat/{roomId}/sendFile` 추가

Resolves: #71
- 확장자 명을 파싱하여 파일 타입으로 반환

Resolves: #71
- ChatFileRequest를 통해 받은 파일 URL 리스트를 통해 파일 타입과 프리사인 URL을 생성하여 응답으로 반환

Resolves: #71
- 메서드의 기능을 알기 쉽도록 간단한 주석을 추가

Resolves: #71
- 긴 메시지 저장이 가능하도록 타입을 TEXT로 변경

Resolves: #71
- ChatMessage
 - sender 필드에 Null 값 들어가지 않도록 설정

- ChatMessageResponse
 - 메시지 내용이 Null이면 빈 문자열 ""를 반환하도록 변경

Resolves: #71
- `/api/chat/messages/{roomId}/search` 엔드포인트로 메시지 검색 가능
- 쿼리 파라미터(?keyword=내용)로 검색하고 싶은 키워드 입력

Resolves: #71
- 읽은 메시지를 관리할 ChatMessageRead Entity, Repository 추가

Resolves: #71
- 메시지 읽음 처리
 - ChatMessageRead 테이블에 없는 메시지는 읽지 않은 메시지
 - 읽지 않은 메시지를 조회하여 ChatMessageRead에 등록

- 안 읽은 메시지 목록 조회
 - ChatMessageRead 테이블에서 유저가 읽은 메시지 리스트 반환
 - 반환 받은 리스트로 안 읽은 메시지를 모두 조회하여 응답

- 안 읽은 메시지 개수 조회
 - ChatMessageRead 테이블에서 유저가 읽은 메시지 리스트 반환
 - 반환 받은 리스트로 ChatMessage 테이블에서 안 읽은 메시지만 필터링하여 카운트

Resolves: #71
- 기존의 조회 응답에서 isRead 필드를 추가하여 읽음 여부도 추가로 응답

Resolves: #71
- ChatMessageResponse의 fromEntity 메서드는 isRead 값 까지 같이 반환
- 검색용 메서드인 fromEntityForSearch를 만들어 isRead 값을 null로 설정
- @JsonInclude(JsonInclude.Include.NON_NULL) 을 이용해 null 값은 응답에서 제외

Resolves: #71
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

채팅 기능
1 participant