-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: 웹소켓 의존성 추가 * feat: 채팅 웹소켓 인터셉터 생성 * feat: 웹소켓 세션 등록 일급컬렉션 추가 * feat: 웹소켓 configuration 추가 * feat: 웹소켓 연결 해제 기능 구현 * refactor: 인터셉터 서비스 구현 및 인가 인터셉터 분리 * feat: 웹소켓 핸들러 생성 * feat: 채팅 웹소켓 url과 인터셉터 지정 * feat: 채팅 웹소켓 url과 인터셉터 지정 * chore: 작업을 위한 임시 세팅 * feat: 채팅 웹소켓 인터셉터 생성 * feat: 웹소켓 세션 등록 일급컬렉션 추가 * feat: 웹소켓 configuration 추가 * feat: 웹소켓 연결 해제 기능 구현 * feat: 웹소켓 핸들러 생성 * feat: 채팅 웹소켓 url과 인터셉터 지정 * chore: 작업을 위한 임시 세팅 * fix: 이미지 절대 url 가져오는 문제 해결 * refactor: 웹소켓 요청 path 변경 * refactor: TextMessage 형식 변경 * refactor: 웹소켓 핸들러 추상화 * fix: 오류가 발생하는 테스트 해결 * test: 테스트 추가 - WebSocketHandleTextMessageProviderCompositeTest * refactor: map 타입에 대한 dto 생성 * refactor: 코드 리팩터링 * refactor: 로직 이동 * refactor: 채팅 알림 전송 로직을 웹 소켓쪽으로 이동 * refactor: 전송자에 대한 변수명 변경 sender -> writer * refactor: attribute 키의 상수명 변경 * refactor: 핸들링하는 메서드에 대한 이름 변경 handle -> handleCreateSendMessage * refactor: dto 변수명 수정 SendMessagesDto -> SendMessageDto SendMessageDto -> MessageDto * refactor: 기존 메시지 생성 로직 제거 * refactor: final 키워드 추가 * test: 테스트 추가 * fix: 전송할 메시지 생성 시 발신자 session으로만 전송되는 문제 수정 * refactor: 메시지 로그 업데이트 이벤트에서 수신자, 채팅방 객체 대신 id 받도록 변경 * style: 메서드 순서 정렬 * feat: 마지막 읽은 메시지 업데이트 이벤트 발행 추가 * test: 실패하는 테스트 수정 * test: 메시지 전송 시 메시지 읽음 처리 이벤트 호출 테스트 추가 * refactor: 중복되는 탈퇴 회원 검증 메서드 삭제 * style: 와일드카드 제거 * style: 불필요한 필드 삭제 * refactor: 메시지 로그 업데이트 시 마지막 메시지 아이디만 받도록 수정 --------- Co-authored-by: JJ503 <[email protected]>
- Loading branch information
Showing
49 changed files
with
1,366 additions
and
358 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
61 changes: 61 additions & 0 deletions
61
...n/java/com/ddang/ddang/authentication/configuration/AuthenticationInterceptorService.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.ddang.ddang.authentication.configuration; | ||
|
||
import com.ddang.ddang.authentication.application.AuthenticationUserService; | ||
import com.ddang.ddang.authentication.application.BlackListTokenService; | ||
import com.ddang.ddang.authentication.domain.TokenDecoder; | ||
import com.ddang.ddang.authentication.domain.TokenType; | ||
import com.ddang.ddang.authentication.domain.dto.AuthenticationStore; | ||
import com.ddang.ddang.authentication.domain.dto.AuthenticationUserInfo; | ||
import com.ddang.ddang.authentication.domain.exception.InvalidTokenException; | ||
import com.ddang.ddang.authentication.infrastructure.jwt.PrivateClaims; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class AuthenticationInterceptorService { | ||
|
||
private final BlackListTokenService blackListTokenService; | ||
private final AuthenticationUserService authenticationUserService; | ||
private final TokenDecoder tokenDecoder; | ||
private final AuthenticationStore store; | ||
|
||
public boolean handleAccessToken(final String accessToken) { | ||
if (isNotRequiredAuthenticate(accessToken)) { | ||
store.set(new AuthenticationUserInfo(null)); | ||
return true; | ||
} | ||
|
||
validateLogoutToken(accessToken); | ||
|
||
final PrivateClaims privateClaims = tokenDecoder.decode(TokenType.ACCESS, accessToken) | ||
.orElseThrow(() -> | ||
new InvalidTokenException("유효한 토큰이 아닙니다.") | ||
); | ||
|
||
if (authenticationUserService.isWithdrawal(privateClaims.userId())) { | ||
throw new InvalidTokenException("유효한 토큰이 아닙니다."); | ||
} | ||
|
||
store.set(new AuthenticationUserInfo(privateClaims.userId())); | ||
return true; | ||
} | ||
|
||
private boolean isNotRequiredAuthenticate(final String token) { | ||
return token == null || token.length() == 0; | ||
} | ||
|
||
private void validateLogoutToken(final String accessToken) { | ||
if (blackListTokenService.existsBlackListToken(TokenType.ACCESS, accessToken)) { | ||
throw new InvalidTokenException("유효한 토큰이 아닙니다."); | ||
} | ||
} | ||
|
||
public void removeStore() { | ||
store.remove(); | ||
} | ||
|
||
public AuthenticationUserInfo getAuthenticationUserInfo() { | ||
return store.get(); | ||
} | ||
} |
This file contains 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
This file contains 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
This file contains 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
6 changes: 1 addition & 5 deletions
6
...ddang/src/main/java/com/ddang/ddang/chat/application/event/UpdateReadMessageLogEvent.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,4 @@ | ||
package com.ddang.ddang.chat.application.event; | ||
|
||
import com.ddang.ddang.chat.domain.ChatRoom; | ||
import com.ddang.ddang.chat.domain.Message; | ||
import com.ddang.ddang.user.domain.User; | ||
|
||
public record UpdateReadMessageLogEvent(User reader, ChatRoom chatRoom, Message lastReadMessage) { | ||
public record UpdateReadMessageLogEvent(Long readerId, Long chatRoomId, Long lastReadMessageId) { | ||
} |
42 changes: 42 additions & 0 deletions
42
backend/ddang/src/main/java/com/ddang/ddang/chat/domain/WebSocketChatSessions.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package com.ddang.ddang.chat.domain; | ||
|
||
import lombok.Getter; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import static com.ddang.ddang.chat.domain.WebSocketSessions.CHAT_ROOM_ID_KEY; | ||
|
||
@Getter | ||
@Component | ||
public class WebSocketChatSessions { | ||
|
||
private final Map<Long, WebSocketSessions> chatRoomSessions = new ConcurrentHashMap<>(); | ||
|
||
public void add(final WebSocketSession session, final Long chatRoomId) { | ||
chatRoomSessions.putIfAbsent(chatRoomId, new WebSocketSessions()); | ||
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId); | ||
webSocketSessions.putIfAbsent(session, chatRoomId); | ||
} | ||
|
||
public Set<WebSocketSession> getSessionsByChatRoomId(final Long chatRoomId) { | ||
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId); | ||
|
||
return webSocketSessions.getSessions(); | ||
} | ||
|
||
public boolean containsByUserId(final Long chatRoomId, final Long userId) { | ||
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId); | ||
|
||
return webSocketSessions.contains(userId); | ||
} | ||
|
||
public void remove(final WebSocketSession session) { | ||
final long chatRoomId = Long.parseLong(String.valueOf(session.getAttributes().get(CHAT_ROOM_ID_KEY))); | ||
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId); | ||
webSocketSessions.remove(session); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
backend/ddang/src/main/java/com/ddang/ddang/chat/domain/WebSocketSessions.java
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.ddang.ddang.chat.domain; | ||
|
||
import lombok.Getter; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
import java.util.Collections; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
@Getter | ||
public class WebSocketSessions { | ||
|
||
protected static final String CHAT_ROOM_ID_KEY = "chatRoomId"; | ||
private static final String USER_ID_KEY = "userId"; | ||
|
||
private final Set<WebSocketSession> sessions = Collections.newSetFromMap(new ConcurrentHashMap<>()); | ||
|
||
public void putIfAbsent(final WebSocketSession session, final Long chatRoomId) { | ||
if (!sessions.contains(session)) { | ||
session.getAttributes().put(CHAT_ROOM_ID_KEY, chatRoomId); | ||
sessions.add(session); | ||
} | ||
} | ||
|
||
public boolean contains(final Long userId) { | ||
return sessions.stream() | ||
.anyMatch(session -> session.getAttributes().get(USER_ID_KEY) == userId); | ||
} | ||
|
||
public void remove(final WebSocketSession session) { | ||
sessions.remove(session); | ||
} | ||
} |
Oops, something went wrong.