-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[BE] SSE 기반 타이머 잔여 시간 조회 기능을 Web Socket 기반으로 변경
- Loading branch information
Showing
19 changed files
with
344 additions
and
11 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
8 changes: 8 additions & 0 deletions
8
backend/src/main/java/site/coduo/pairroom/exception/NotFoundPairRoomSessionException.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,8 @@ | ||
package site.coduo.pairroom.exception; | ||
|
||
public class NotFoundPairRoomSessionException extends PairRoomException { | ||
|
||
public NotFoundPairRoomSessionException(final String message) { | ||
super(message); | ||
} | ||
} |
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
25 changes: 25 additions & 0 deletions
25
backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.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,25 @@ | ||
package site.coduo.websocket; | ||
|
||
import java.util.Set; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class PairRoomWebSocketService { | ||
|
||
private final PairRoomWebSocketSessionStore pairRoomWebSocketSessionStore; | ||
private final WebSocketSender prodWebSocketSender; | ||
|
||
public void sendAllPairRoomSessions(final String pairRoomAccessCode, final WebSocketMessage message) { | ||
final Set<WebSocketSession> sessions = pairRoomWebSocketSessionStore.getSessions(pairRoomAccessCode); | ||
prodWebSocketSender.sendMessage(sessions, message); | ||
} | ||
|
||
public boolean hasNoConnections(final String pairRoomAccessCode) { | ||
return !pairRoomWebSocketSessionStore.hasPairRoomSessions(pairRoomAccessCode); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
backend/src/main/java/site/coduo/websocket/PairRoomWebSocketSessionStore.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,54 @@ | ||
package site.coduo.websocket; | ||
|
||
import java.util.HashSet; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import site.coduo.pairroom.exception.InvalidAccessCodeException; | ||
import site.coduo.pairroom.exception.NotFoundPairRoomSessionException; | ||
import site.coduo.pairroom.exception.PairRoomNotFoundException; | ||
import site.coduo.pairroom.repository.PairRoomRepository; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class PairRoomWebSocketSessionStore { | ||
|
||
private final PairRoomRepository pairRoomRepository; | ||
private final Map<String, Set<WebSocketSession>> sessions = new ConcurrentHashMap<>(); | ||
|
||
public void addSession(final String pairRoomAccessCode, final WebSocketSession session) { | ||
validatePairRoomAccessCode(pairRoomAccessCode); | ||
if (!sessions.containsKey(pairRoomAccessCode)) { | ||
sessions.put(pairRoomAccessCode, new HashSet<>()); | ||
} | ||
sessions.get(pairRoomAccessCode).add(session); | ||
} | ||
|
||
private void validatePairRoomAccessCode(final String pairRoomAccessCode) { | ||
if (pairRoomAccessCode == null || pairRoomAccessCode.isBlank()) { | ||
throw new InvalidAccessCodeException("페어룸 접근 코드로 null이 입력될 수 없습니다."); | ||
} | ||
|
||
if (!pairRoomRepository.existsByAccessCode(pairRoomAccessCode)) { | ||
throw new PairRoomNotFoundException("존재하지 않는 페어룸 코드입니다. - " + pairRoomAccessCode); | ||
} | ||
} | ||
|
||
public Set<WebSocketSession> getSessions(final String pairRoomAccessCode) { | ||
validatePairRoomAccessCode(pairRoomAccessCode); | ||
if (!sessions.containsKey(pairRoomAccessCode)) { | ||
throw new NotFoundPairRoomSessionException("해당 페어룸의 세션이 존재하지 않습니다. - " + pairRoomAccessCode); | ||
} | ||
return sessions.get(pairRoomAccessCode); | ||
} | ||
|
||
public boolean hasPairRoomSessions(final String pairRoomAccessCode) { | ||
validatePairRoomAccessCode(pairRoomAccessCode); | ||
return sessions.containsKey(pairRoomAccessCode); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
backend/src/main/java/site/coduo/websocket/ProdWebSocketSender.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,35 @@ | ||
package site.coduo.websocket; | ||
|
||
import java.io.IOException; | ||
import java.util.Set; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.TextMessage; | ||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Component | ||
public class ProdWebSocketSender implements WebSocketSender { | ||
|
||
private final ObjectMapper objectMapper; | ||
|
||
@Override | ||
public void sendMessage(final Set<WebSocketSession> sessions, final WebSocketMessage message) { | ||
sessions.parallelStream().forEach(session -> sendMessage(session, message)); | ||
} | ||
|
||
private void sendMessage(final WebSocketSession session, final WebSocketMessage message) { | ||
try { | ||
final TextMessage webSocketMessage = new TextMessage(objectMapper.writeValueAsString(message)); | ||
session.sendMessage(webSocketMessage); | ||
} catch (IOException e) { | ||
log.error(e.getMessage(), e); | ||
} | ||
} | ||
} |
38 changes: 38 additions & 0 deletions
38
backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.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,38 @@ | ||
package site.coduo.websocket; | ||
|
||
import java.net.URLDecoder; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Arrays; | ||
|
||
import site.coduo.websocket.exception.EmptyQueryException; | ||
import site.coduo.websocket.exception.NotFoundAccessCodeInQueryException; | ||
|
||
public class QueryAccessCodeParser { | ||
|
||
private static final String QUERY_DELIMITER = "&"; | ||
private static final String KEY_VALUE_DELIMITER = "="; | ||
private static final int ACCESS_CODE_QUERY_SIZE = 2; | ||
private static final int KEY_INDEX = 0; | ||
private static final String ACCESS_CODE_KEY_NAME = "accesscode"; | ||
private static final int VALUE_INDEX = 1; | ||
|
||
public static String parse(final String query) { | ||
validateQuery(query); | ||
return Arrays.stream(query.split(QUERY_DELIMITER)) | ||
.map(keyValuePair -> keyValuePair.split(KEY_VALUE_DELIMITER)) | ||
.filter(QueryAccessCodeParser::isAccessCodeKeyValuePair) | ||
.findFirst() | ||
.map(accessCodeKeyValue -> URLDecoder.decode(accessCodeKeyValue[VALUE_INDEX], StandardCharsets.UTF_8)) | ||
.orElseThrow(() -> new NotFoundAccessCodeInQueryException("쿼리에 액세스코드가 존재하지 않습니다.")); | ||
} | ||
|
||
private static void validateQuery(final String query) { | ||
if (query == null || query.isEmpty()) { | ||
throw new EmptyQueryException("쿼리가 존재하지 않습니다."); | ||
} | ||
} | ||
|
||
private static boolean isAccessCodeKeyValuePair(final String[] keyValuePair) { | ||
return keyValuePair.length == ACCESS_CODE_QUERY_SIZE && keyValuePair[KEY_INDEX].equals(ACCESS_CODE_KEY_NAME); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
backend/src/main/java/site/coduo/websocket/WebSocketConfig.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,22 @@ | ||
package site.coduo.websocket; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.socket.config.annotation.EnableWebSocket; | ||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; | ||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
|
||
@RequiredArgsConstructor | ||
@EnableWebSocket | ||
@Configuration | ||
public class WebSocketConfig implements WebSocketConfigurer { | ||
|
||
private final WebSocketHandler webSocketHandler; | ||
|
||
@Override | ||
public void registerWebSocketHandlers(final WebSocketHandlerRegistry registry) { | ||
registry.addHandler(webSocketHandler, "/ws-connect") | ||
.setAllowedOrigins("*"); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
backend/src/main/java/site/coduo/websocket/WebSocketHandler.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,41 @@ | ||
package site.coduo.websocket; | ||
|
||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.CloseStatus; | ||
import org.springframework.web.socket.TextMessage; | ||
import org.springframework.web.socket.WebSocketSession; | ||
import org.springframework.web.socket.handler.TextWebSocketHandler; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
@Component | ||
public class WebSocketHandler extends TextWebSocketHandler { | ||
|
||
private final PairRoomWebSocketSessionStore pairRoomWebSocketSessionStore; | ||
|
||
@Override | ||
public void afterConnectionEstablished(final WebSocketSession session) { | ||
final String query = session.getUri().getQuery(); | ||
final String pairRoomAccessCode = QueryAccessCodeParser.parse(query); | ||
pairRoomWebSocketSessionStore.addSession(pairRoomAccessCode, session); | ||
log.info("연결 성공 : {}", session.getId()); | ||
} | ||
|
||
@Override | ||
protected void handleTextMessage(final WebSocketSession session, final TextMessage message) { | ||
// TODO : 클라이언트의 메시지를 파싱하는 메서드. 타이머 잔여 시간 조회에 필요가 없어 우선 보류 | ||
} | ||
|
||
@Override | ||
public void handleTransportError(final WebSocketSession session, final Throwable exception) { | ||
log.error("Web Socket 전송 중 에러 발생 : {}", exception.getMessage()); | ||
} | ||
|
||
@Override | ||
public void afterConnectionClosed(final WebSocketSession session, final CloseStatus status) { | ||
log.info("연결 종료 : {}, 상태 : {}", session.getId(), status); | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
backend/src/main/java/site/coduo/websocket/WebSocketMessage.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,4 @@ | ||
package site.coduo.websocket; | ||
|
||
public interface WebSocketMessage { | ||
} |
10 changes: 10 additions & 0 deletions
10
backend/src/main/java/site/coduo/websocket/WebSocketSender.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,10 @@ | ||
package site.coduo.websocket; | ||
|
||
import java.util.Set; | ||
|
||
import org.springframework.web.socket.WebSocketSession; | ||
|
||
public interface WebSocketSender { | ||
|
||
void sendMessage(final Set<WebSocketSession> sessions, final WebSocketMessage message); | ||
} |
8 changes: 8 additions & 0 deletions
8
backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.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,8 @@ | ||
package site.coduo.websocket.exception; | ||
|
||
public class EmptyQueryException extends WebSocketException { | ||
|
||
public EmptyQueryException(final String message) { | ||
super(message); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.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,8 @@ | ||
package site.coduo.websocket.exception; | ||
|
||
public class NotFoundAccessCodeInQueryException extends WebSocketException { | ||
|
||
public NotFoundAccessCodeInQueryException(final String message) { | ||
super(message); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
backend/src/main/java/site/coduo/websocket/exception/WebSocketException.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,8 @@ | ||
package site.coduo.websocket.exception; | ||
|
||
public class WebSocketException extends RuntimeException { | ||
|
||
public WebSocketException(final String message) { | ||
super(message); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
backend/src/main/java/site/coduo/websocket/message/EventAndDataMessage.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,6 @@ | ||
package site.coduo.websocket.message; | ||
|
||
import site.coduo.websocket.WebSocketMessage; | ||
|
||
public record EventAndDataMessage(String event, String data) implements WebSocketMessage { | ||
} |
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
Oops, something went wrong.