1. 사용자가 오픈런 게시글 목록 조회 api 호출
→ 공개중인 게시글과 공개예정 게시글 한 번에 보여줌
=> api 호출로 목록을 화면에 먼저 띄우고, 이후에 바로 소켓 연결을 하는 게 합리적
(클라이언트 측에서 동기적으로 수행)
2. 클라이언트 : 소켓 연결 & 해당 페이지의 게시글들을 sub
=> 페이지에 해당하는 모든 게시글을 한 번에 subscribe 할 수 없음
클라이언트 측에서 반복문을 돌면서 하나씩 subscribe 요청 필요
왜냐면!
특정 토픽 경로를 구독하는 건 서버가 아니라 클라이언트가 할 일
한 유저가 여러 게시글에 대해 구독하려면 이렇게 반복문을 돌면서 하나씩 구독 요청을 보내야 함
boardIds.forEach(id => {
stompClient.subscribe(`/topic/openrun/board/${id}`, message => {
// 메시지 수신 처리
});
});
한 번에 여러 게시글을 구독하려면?
payload에 여러개의 게시글 id를 담아서 메세지를 전송
→ 게시글 중 하나의 게시글이 상태가 변경되면 아래와 같이 어떤 boardId에 대해 값이 변경되었는지 확인 필요
→ 모든 게시글이 하나의 topic 경로로 메세지를 전송하기 때문에 메세지 수신이 빈번하게 발생
→ topic 경로가 하나이기 때문에 내가 구독하지 않은 게시글의 변경 상태도 수신될 수 있음(모든 유저가 하나의 경로를 사용하므로)
ex. A유저가 게시글 1,2,3 구독 / B유저가 게시글 4,5,6 구독 ⇒ A유저와 B유저는 1~6 게시글 상태 모두 수신
stompClient.subscribe("/topic/openrun/board", message => {
const { boardId, message } = JSON.parse(message.body);
});
//수신하는 json 예시
{
"boardId": 3,
"remainingSlot": 5
}
topic 경로에 user 정보를 포함하여 사용자마다 다른 경로로 메세지를 수신한다면?
- 클라이언트가 /topic/openrun/board/{userId} 경로를 구독하고 payload에 구독할 게시글들의 id를 담아서 전송
- 서버는 userId, boardId를 Redis나 Map에 저장
- 게시글 상태가 바뀌면 Redis나 Map에서 해당 게시글을 구독한 userId를 찾아 /topic/openrun/board/{userId} 경로로 메세지 전송
또는 경로에 userId를 넣지 않고도, 인터셉터에서 추출한 userId를 사용해서 특정 유저에게만 전송하는 방법도 있지만 이 방식은 주로 채팅, 알림처럼 1:1 알림이 주된 케이스에서 사용함
- @SendToUser 어노테이션을 컨트롤러에 적용해서 요청이 들어왔을 때 바로 해당 유저에게 메시지 응답(즉시 응답 필수)
- @MessageMapping("/openrun/subscribe") @SendToUser("/queue/subscription-result") public SubscriptionResponse handleSubscribe(SubscriptionRequest request, Principal principal) { return new SubscriptionResponse("Subscribed successfully"); }
- 시간차를 두고, 특정 이벤트가 발생한 시점에 특정 유저에게 메세지를 전송하려면 수동으로 메세지 전송
- messagingTemplate.convertAndSendToUser( userId, // Principal.getName()과 일치해야 함 "/queue/reply", payload );
→ 경로에 userId를 넣어서 사용하는 방법은 해당 경로를 한 명의 유저가 단독으로 사용하게 되는 시스템인데, 이 방식은 STOMP 송수신에 적합하지 않은 방식(STOMP는 pub/sub 방식을 기반으로 설계됨)
→ Redis나 Map에 userId, boardId를 저장/갱신/추적하는 과정은 불필요한 관리 비용 발생
결론
최상단 방법처럼 클라이언트에서 반복적으로 각 boardId 경로를 구독하는 방식이 가장 효율적
3. 서버 : 클라이언트에 잔여시간/인원 값 변경될 때마다 pub
잔여 시간의 경우는 따로 값 변경될때마다 알려주지 말고 openLimit 클라이언트한테 알려주면 클라이언트가 알아서 처리
잔여 인원의 경우 zset에 데이터가 삽입될 때마다 메세지 전송
'프로젝트 > 팀 프로젝트' 카테고리의 다른 글
| [팀 뜯먹파] @modifying → 트랜잭션 적용 필요 (0) | 2025.07.16 |
|---|---|
| [팀 뜯먹파] 선착순 sorted set에 유저 데이터 삽입시 발생하는 동시성 문제 해결 (0) | 2025.07.11 |
| [팀 뜯먹파] 스케줄러 사용 시 주의사항 및 개선 방법 (0) | 2025.07.09 |
| [팀 뜯먹파] 오픈런 게시글 상태 관리 (0) | 2025.07.04 |
| [팀 뜯먹파] queryDSL, JPQL, Native Query (+ jooq, mapper) (0) | 2025.07.02 |

