Merged
Conversation
Closed
6d504a7 to
6181bed
Compare
📊 코드 커버리지 리포트
|
7bca341 to
54e0734
Compare
minibr
approved these changes
Dec 18, 2025
src/main/java/com/sofa/linkiving/domain/chat/service/MessageService.java
Show resolved
Hide resolved
afb0f0b to
fb86794
Compare
fb86794 to
eaa509a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
관련 이슈
PR 설명
WebSocket(STOMP)과WebFlux(Reactor)를 활용하여 비동기 논블로킹 방식으로 AI 응답 처리동작 흐름 (Operation Flow)
1. 연결 및 구독 (Connection)
ws://{domain}/ws/chat엔드포인트로 연결을 수립함./topic/chat/{chatId}경로를 구독하여 메시지 수신 대기 상태로 진입함.2. 답변 생성 (Generate)
/app/send/{chatId}로 질문 메시지 전송.MessageService)가WebClient를 통해 AI 서버로 비동기 요청 전송.WebSocket을 통해 토큰 단위로 클라이언트에게 실시간 푸시.END_OF_STREAM메시지 전송 및 전체 대화 내용 DB 저장.3. 답변 취소 (Cancel)
/app/cancel/{chatId}로 취소 요청 전송.SubscriptionManager가 해당 채팅방의 활성 구독(Disposable)을 즉시 해제(dispose).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. 테스트 작성 (통합 및 유닛 테스트)
WebSocketChatIntegrationTest):WebSocketStompClient)을 구축하여 연결, 구독, 메시지 전송, 스트리밍 수신, 취소 기능까지 전체 흐름을 검증함.ReflectionTestUtils로WebClient타겟을MockAiController로 변경하여 외부 AI 서버 없이 테스트 가능하도록 구성함.SubscriptionManagerTest: 구독 추가, 취소, 제거 시Disposable자원 해제가 올바르게 호출되는지 검증함.MessageServiceTest: 답변 취소 시 구독 해제 및 취소 메시지 전송 여부, 중복 요청 무시 로직을 테스트함.ChatQueryServiceTest: 존재하지 않는 채팅방 조회 시 예외 처리(CHAT_NOT_FOUND)를 확인함.ChatRepositoryTest):getChatByIdAndMember메서드가 본인의 채팅방만 조회하고, 타인의 채팅방 접근 시Empty를 반환하는지 확인함.테스트 방법
1. 테스트 페이지 생성 (
src/main/resources/static/chat.html)/topic/chat/{chatId}구독 및 메시지 수신.2. Security 설정 허용 (
SecurityConfig)chat.html)에 브라우저에서 직접 접근할 수 있도록PERMIT_URLS목록에/chat.html을 추가합니다.3. 테스트 실행 순서
http://localhost:8080/chat.html접속.AccessToken입력 및chatId입력 후연결버튼 클릭.