1) 사용자 A가 DizzyCode 로그인:
-
웹소켓 연결 👉 상세보기
[client]
- JWT를 사용하여 Secondary Token 발급을 요청한다.
[server]
- 서버는 클라이언트가 JWT를 보내면, 이를 검증한 후 ST를 반환한다.
- 이때 유효기간은 30초 정도로 매우 짧게 둔다.
[client]
- ST를 쿼리 파라미터에 넣어서 보내 웹소켓 업그레이드를 요청한다.
[server]
- HandshakeInterceptor를 사용하여 ST를 추출하고 검증한다.
- 웹소켓 연결 시 유효기간이 짧은 secondary token을 도입해 초기 연결의 보안성을 높이고, 이후의 STOMP 연결과 메시지 전송 과정에서는 JWT를 사용하여 지속적인 인증 및 권한 관리 수행
-
연결 성공 시 A가 속한 모든 방들 subscribe
- 여기로 온 메시지들은 {roomId, categoryId, channelId} 형식으로 오며, 채널에 온 새로운 채팅 알림을 위함
2) A가 채팅하기 위해 채널1에 들어감:
-
채널1 subscribe
- 해당 경로로 온 메시지들은 화면에 바로바로 업데이트
-
메시지 보낼 때 app 토픽으로 publish
if (client && isConnected) { const destination = `/app/rooms.${roomId}.categories.${categoryId}.channels.${channelId}`; client.publish({ destination, headers: { Authorization: `Bearer ${localStorage.getItem('accessToken')}`, }, body: JSON.stringify(body), }); }
3) 채널1 퇴장, 채널2 입장:
- 채널1 unsubscribe, 채널2 subscribe
4) 로그아웃:
- 모든 방, 채널 구독 취소, 웹소켓 연결 종료
기능
- TanStack Query의 useInfiniteQuery를 활용해 채팅 메시지를 20개씩 끊어서 요청
원리
- 첫 로드 시, 초기 20개의 메시지를 가져옴.
- 스크롤이 특정 지점에 도달하면 fetchNextPage를 호출하여 추가 메시지를 로드.
- 이전에 가져온 데이터를 유지하면서 새로운 데이터만 추가.
효과
- 필요 이상의 데이터 로딩을 방지하여 성능 최적화
기능
- 한번 들어온 채팅방의 데이터를 TanStack Query의 캐시에 저장하여, 동일한 채팅방으로 재입장 시 네트워크 요청을 최소화.
원리
- 채팅방 데이터는 쿼리키 ['chats', currentChannelPath]를 기반으로 캐시에 저장됨.
- currentChannelPath가 동일한 요청은 캐싱된 데이터를 반환하며 불필요한 네트워크 호출 방지
효과
- 네트워크 부하 감소
- 캐싱된 데이터를 즉시 로드하여 빠른 사용자 경험 제공