Skip to content

채팅 답변 생성 및 취소 API 구현#127

Merged
ckdals4600 merged 1 commit intomainfrom
feature/#113-chat-answer-create-answer
Dec 19, 2025
Merged

채팅 답변 생성 및 취소 API 구현#127
ckdals4600 merged 1 commit intomainfrom
feature/#113-chat-answer-create-answer

Conversation

@ckdals4600
Copy link
Contributor

@ckdals4600 ckdals4600 commented Dec 14, 2025

관련 이슈

PR 설명

  • 사용자의 질문에 대해 AI 답변을 실시간 스트리밍으로 제공하고, 필요 시 생성을 즉시 취소할 수 있는 기능을 구현함.
  • WebSocket(STOMP)WebFlux(Reactor)를 활용하여 비동기 논블로킹 방식으로 AI 응답 처리

동작 흐름 (Operation Flow)

1. 연결 및 구독 (Connection)

  1. Socket 연결: 클라이언트가 ws://{domain}/ws/chat 엔드포인트로 연결을 수립함.
  2. 구독 (Subscribe): 클라이언트가 /topic/chat/{chatId} 경로를 구독하여 메시지 수신 대기 상태로 진입함.

2. 답변 생성 (Generate)

  1. 질문 전송: 클라이언트가 /app/send/{chatId}로 질문 메시지 전송.
  2. AI 요청 (Async): 서버(MessageService)가 WebClient를 통해 AI 서버로 비동기 요청 전송.
  3. 스트리밍: AI 응답이 오는 즉시 WebSocket을 통해 토큰 단위로 클라이언트에게 실시간 푸시.
  4. 완료 처리: 스트림 종료 시 END_OF_STREAM 메시지 전송 및 전체 대화 내용 DB 저장.

3. 답변 취소 (Cancel)

  1. 취소 요청: 클라이언트가 답변 생성 중 /app/cancel/{chatId}로 취소 요청 전송.
  2. 리소스 해제: SubscriptionManager가 해당 채팅방의 활성 구독(Disposable)을 즉시 해제(dispose).
  3. 중단 알림: 클라이언트에게 GENERATION_CANCELLED 메시지를 전송하고 스트림 종료.

작업 내용

1. WebSocket 및 비동기 환경 설정

  • WebSocketConfig: STOMP 엔드포인트(/ws/chat) 설정 및 메시지 브로커(/topic)를 구성함.
  • WebMvcConfig: 비동기 작업 처리를 위한 mvcTaskExecutor 설정을 추가함.
  • StompHandler: WebSocket 연결 시 JWT 토큰을 검증하고 인증 정보(Authentication)를 주입하는 인터셉터를 구현함.

2. 비즈니스 로직 (MessageService, SubscriptionManager)

  • 스트리밍 아키텍처: WebClient를 사용하여 AI 서버로부터 스트림 데이터를 수신(Flux)하고, SimpMessagingTemplate으로 실시간 전송함.
  • 취소 기능: SubscriptionManager를 통해 활성 구독(Disposable)을 관리하며, 취소 요청 시 즉시 자원을 해제함.
  • 중복 방지: MessageService 내부 버퍼를 확인하여 이미 답변 생성 중인 채팅방에 대한 중복 요청을 무시함.

3. 테스트 작성 (통합 및 유닛 테스트)

  • Integration Test (WebSocketChatIntegrationTest):
    • 실제 웹소켓 환경(WebSocketStompClient)을 구축하여 연결, 구독, 메시지 전송, 스트리밍 수신, 취소 기능까지 전체 흐름을 검증함.
    • ReflectionTestUtilsWebClient 타겟을 MockAiController로 변경하여 외부 AI 서버 없이 테스트 가능하도록 구성함.
  • Unit Test (Service/Manager Layer):
    • SubscriptionManagerTest: 구독 추가, 취소, 제거 시 Disposable 자원 해제가 올바르게 호출되는지 검증함.
    • MessageServiceTest: 답변 취소 시 구독 해제 및 취소 메시지 전송 여부, 중복 요청 무시 로직을 테스트함.
    • ChatQueryServiceTest: 존재하지 않는 채팅방 조회 시 예외 처리(CHAT_NOT_FOUND)를 확인함.
  • Repository Test (ChatRepositoryTest):
    • 보안 검증: getChatByIdAndMember 메서드가 본인의 채팅방만 조회하고, 타인의 채팅방 접근 시 Empty를 반환하는지 확인함.

테스트 방법

1. 테스트 페이지 생성 (src/main/resources/static/chat.html)

  • 기능:
    • JWT 토큰 기반 STOMP 연결.
    • /topic/chat/{chatId} 구독 및 메시지 수신.
    • 메시지 전송 및 답변 생성 취소 버튼 구현.
  • 파일 내용: chat.html

2. Security 설정 허용 (SecurityConfig)

  • 테스트 페이지(chat.html)에 브라우저에서 직접 접근할 수 있도록 PERMIT_URLS 목록에 /chat.html을 추가합니다.

3. 테스트 실행 순서

  1. 서버 실행 후 http://localhost:8080/chat.html 접속.
  2. 발급받은 AccessToken 입력 및 chatId 입력 후 연결 버튼 클릭.
  3. 메시지 전송 및 취소 기능 테스트.

@ckdals4600 ckdals4600 linked an issue Dec 14, 2025 that may be closed by this pull request
@ckdals4600 ckdals4600 requested review from Goder-0 and minibr December 14, 2025 20:45
@ckdals4600 ckdals4600 self-assigned this Dec 14, 2025
@ckdals4600 ckdals4600 force-pushed the feature/#113-chat-answer-create-answer branch from 6d504a7 to 6181bed Compare December 14, 2025 20:50
@github-actions
Copy link

github-actions bot commented Dec 14, 2025

📊 코드 커버리지 리포트

Overall Project 90.95% -2.51% 🍏
Files changed 82.96% 🍏

File Coverage
MessageCommandService.java 100% 🍏
ChatQueryService.java 100% 🍏
ChatService.java 100% 🍏
RedisService.java 100% 🍏
SubscriptionManager.java 100% 🍏
ChatFacade.java 100% 🍏
MockAiController.java 100% 🍏
ChatController.java 100% 🍏
ChatErrorCode.java 100% 🍏
AuthMemberWebsocketArgumentResolver.java 88.37% -11.63% 🍏
MessageService.java 62.42% -37.58% 🍏

@ckdals4600 ckdals4600 force-pushed the feature/#113-chat-answer-create-answer branch 3 times, most recently from 7bca341 to 54e0734 Compare December 15, 2025 15:01
@ckdals4600 ckdals4600 force-pushed the feature/#113-chat-answer-create-answer branch 2 times, most recently from afb0f0b to fb86794 Compare December 18, 2025 19:33
@ckdals4600 ckdals4600 force-pushed the feature/#113-chat-answer-create-answer branch from fb86794 to eaa509a Compare December 19, 2025 10:04
@ckdals4600 ckdals4600 merged commit 4509455 into main Dec 19, 2025
1 check passed
@ckdals4600 ckdals4600 deleted the feature/#113-chat-answer-create-answer branch December 19, 2025 10:07
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.

채팅 답변 생성 및 취소 API 개발

2 participants