Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
aad1081
:recycle: exit 응답 추가
sehee123 Jul 20, 2025
c512117
chore: Java 스타일 수정
Jul 20, 2025
4e7b82d
Merge remote-tracking branch 'origin/dev' into refactor/96
sehee123 Jul 21, 2025
ffed8f0
:recycle: convertAndSendToUser 작업 중간 커밋
sehee123 Jul 21, 2025
b934073
Merge remote-tracking branch 'origin/dev' into refactor/96
sehee123 Jul 23, 2025
059ca0d
:sparkles: 1:1 메세징 구현
sehee123 Jul 23, 2025
5277c7c
:bug: 삭제 시 인원 카운트 조건 변경
sehee123 Jul 23, 2025
924286d
Merge remote-tracking branch 'origin/refactor/96' into refactor/96
sehee123 Jul 23, 2025
f06fa7c
chore: Java 스타일 수정
Jul 23, 2025
a6928e5
:mute: yml 로깅 설정 삭제
sehee123 Jul 23, 2025
d22020d
Merge remote-tracking branch 'origin/refactor/96' into refactor/96
sehee123 Jul 23, 2025
67631e6
:mute: securityConfig 테스트용 경로 삭제
sehee123 Jul 23, 2025
ddcc137
:coffin: /me api 응답 수정
sehee123 Jul 23, 2025
5110aed
:adhesive_bandage: isSuccess -> success 필드명 변경
sehee123 Jul 23, 2025
5865945
:adhesive_bandage: reconnect_private 메세지 추가, 재연결시 응답 request_start 제거
sehee123 Jul 25, 2025
4b21714
chore: Java 스타일 수정
Jul 25, 2025
92c73b8
Merge remote-tracking branch 'origin/dev' into refactor/96
sehee123 Jul 25, 2025
a9cfba4
:twisted_rightwards_arrows: dev merge
sehee123 Jul 25, 2025
20dc276
Merge remote-tracking branch 'origin/refactor/96' into refactor/96
sehee123 Jul 25, 2025
2f689e3
:twisted_rightwards_arrows: dev merge
sehee123 Jul 25, 2025
dc4fd0b
:twisted_rightwards_arrows: dev merge
sehee123 Jul 25, 2025
6ec049f
:adhesive_bandage: systemNotice 메세지 수정
sehee123 Jul 25, 2025
d6061d0
Merge remote-tracking branch 'origin/dev' into refactor/96
sehee123 Jul 25, 2025
ae77da3
Merge remote-tracking branch 'origin/dev' into refactor/96
sehee123 Jul 25, 2025
9239461
:twisted_rightwards_arrows: dev merge
sehee123 Jul 25, 2025
6c4ce37
chore: Java 스타일 수정
Jul 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@
import io.f1.backend.domain.admin.dto.AdminPrincipal;
import io.f1.backend.domain.user.dto.UserPrincipal;

public record CurrentUserAndAdminResponse(Long id, String name, String role, String providerId) {
public record CurrentUserAndAdminResponse(Long id, String name, String role) {

public static CurrentUserAndAdminResponse from(UserPrincipal userPrincipal) {
return new CurrentUserAndAdminResponse(
userPrincipal.getUserId(),
userPrincipal.getUserNickname(),
UserPrincipal.ROLE_USER,
userPrincipal.getName());
UserPrincipal.ROLE_USER);
}

public static CurrentUserAndAdminResponse from(AdminPrincipal adminPrincipal) {
return new CurrentUserAndAdminResponse(
adminPrincipal.getAuthenticationAdmin().adminId(),
adminPrincipal.getUsername(),
AdminPrincipal.ROLE_ADMIN,
null);
AdminPrincipal.ROLE_ADMIN);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ public void gameStart(Long roomId, UserPrincipal principal) {

timerService.startTimer(room, START_DELAY);

messageSender.send(destination, MessageType.GAME_START, toGameStartResponse(questions));
messageSender.send(
messageSender.sendBroadcast(
destination, MessageType.GAME_START, toGameStartResponse(questions));
messageSender.sendBroadcast(
destination,
MessageType.QUESTION_START,
toQuestionStartResponse(room, START_DELAY));
Expand All @@ -86,7 +87,7 @@ public void handlePlayerReady(Long roomId, String sessionId) {

PlayerListResponse playerListResponse = toPlayerListResponse(room);
log.info(playerListResponse.toString());
messageSender.send(destination, MessageType.PLAYER_LIST, playerListResponse);
messageSender.sendBroadcast(destination, MessageType.PLAYER_LIST, playerListResponse);
}

public void changeGameSetting(
Expand Down Expand Up @@ -161,7 +162,7 @@ private void toggleReadyIfPossible(Room room, Player player) {
private void broadcastGameSetting(Room room) {
String destination = getDestination(room.getId());
Quiz quiz = quizService.getQuizWithQuestionsById(room.getGameSetting().getQuizId());
messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.GAME_SETTING,
toGameSettingResponse(room.getGameSetting(), quiz));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.f1.backend.domain.game.app;

import static io.f1.backend.domain.game.app.GameService.START_DELAY;
import static io.f1.backend.domain.game.mapper.RoomMapper.ofPlayerEvent;
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSetting;
import static io.f1.backend.domain.game.mapper.RoomMapper.toGameSettingResponse;
Expand All @@ -21,6 +20,7 @@
import io.f1.backend.domain.game.dto.RoomEventType;
import io.f1.backend.domain.game.dto.request.RoomCreateRequest;
import io.f1.backend.domain.game.dto.request.RoomValidationRequest;
import io.f1.backend.domain.game.dto.response.ExitSuccessResponse;
import io.f1.backend.domain.game.dto.response.GameSettingResponse;
import io.f1.backend.domain.game.dto.response.PlayerListResponse;
import io.f1.backend.domain.game.dto.response.RoomCreateResponse;
Expand Down Expand Up @@ -149,10 +149,12 @@ public void initializeRoomSocket(Long roomId, String sessionId, UserPrincipal pr

String destination = getDestination(roomId);

messageSender.send(destination, MessageType.ROOM_SETTING, roomSettingResponse);
messageSender.send(destination, MessageType.GAME_SETTING, gameSettingResponse);
messageSender.send(destination, MessageType.PLAYER_LIST, playerListResponse);
messageSender.send(destination, MessageType.SYSTEM_NOTICE, systemNoticeResponse);
messageSender.sendPersonal(
getUserDestination(), MessageType.GAME_SETTING, gameSettingResponse, principal);

messageSender.sendBroadcast(destination, MessageType.ROOM_SETTING, roomSettingResponse);
messageSender.sendBroadcast(destination, MessageType.PLAYER_LIST, playerListResponse);
messageSender.sendBroadcast(destination, MessageType.SYSTEM_NOTICE, systemNoticeResponse);
}

public void exitRoom(Long roomId, String sessionId, UserPrincipal principal) {
Expand All @@ -166,6 +168,12 @@ public void exitRoom(Long roomId, String sessionId, UserPrincipal principal) {

String destination = getDestination(roomId);

messageSender.sendPersonal(
getUserDestination(),
MessageType.EXIT_SUCCESS,
new ExitSuccessResponse(true),
principal);

/* 방 삭제 */
if (room.isLastPlayer(sessionId)) {
removeRoom(room);
Expand All @@ -185,8 +193,9 @@ public void exitRoom(Long roomId, String sessionId, UserPrincipal principal) {

PlayerListResponse playerListResponse = toPlayerListResponse(room);

messageSender.send(destination, MessageType.PLAYER_LIST, playerListResponse);
messageSender.send(destination, MessageType.SYSTEM_NOTICE, systemNoticeResponse);
messageSender.sendBroadcast(destination, MessageType.PLAYER_LIST, playerListResponse);
messageSender.sendBroadcast(
destination, MessageType.SYSTEM_NOTICE, systemNoticeResponse);
}
}

Expand All @@ -212,7 +221,7 @@ public void chat(Long roomId, String sessionId, ChatMessage chatMessage) {

String destination = getDestination(roomId);

messageSender.send(destination, MessageType.CHAT, chatMessage);
messageSender.sendBroadcast(destination, MessageType.CHAT, chatMessage);

if (!room.isPlaying()) {
return;
Expand All @@ -225,12 +234,13 @@ public void chat(Long roomId, String sessionId, ChatMessage chatMessage) {
if (answer.equals(chatMessage.message())) {
room.increasePlayerCorrectCount(sessionId);

messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.QUESTION_RESULT,
toQuestionResultResponse(chatMessage.nickname(), answer));
messageSender.send(destination, MessageType.RANK_UPDATE, toRankUpdateResponse(room));
messageSender.send(
messageSender.sendBroadcast(
destination, MessageType.RANK_UPDATE, toRankUpdateResponse(room));
messageSender.sendBroadcast(
destination,
MessageType.SYSTEM_NOTICE,
ofPlayerEvent(chatMessage.nickname(), RoomEventType.CORRECT_ANSWER));
Expand All @@ -247,7 +257,7 @@ public void chat(Long roomId, String sessionId, ChatMessage chatMessage) {

// 타이머 추가하기
timerService.startTimer(room, CONTINUE_DELAY);
messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.QUESTION_START,
toQuestionStartResponse(room, CONTINUE_DELAY));
Expand All @@ -260,20 +270,30 @@ public void reconnectSession(
room.reconnectSession(oldSessionId, newSessionId);

String destination = getDestination(roomId);
String userDestination = getUserDestination();

messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.SYSTEM_NOTICE,
ofPlayerEvent(principal.getUserNickname(), RoomEventType.RECONNECT));

if (room.isPlaying()) {
// todo 랭킹 리스트 추가
messageSender.send(
destination, MessageType.GAME_START, toGameStartResponse(room.getQuestions()));
messageSender.send(
destination,
MessageType.QUESTION_START,
toQuestionStartResponse(room, START_DELAY));
messageSender.sendPersonal(
userDestination,
MessageType.SYSTEM_NOTICE,
ofPlayerEvent(
principal.getUserNickname(), RoomEventType.RECONNECT_PRIVATE_NOTICE),
principal);
messageSender.sendPersonal(
userDestination,
MessageType.RANK_UPDATE,
toRankUpdateResponse(room),
principal);
messageSender.sendPersonal(
userDestination,
MessageType.GAME_START,
toGameStartResponse(room.getQuestions()),
principal);
} else {
RoomSettingResponse roomSettingResponse = toRoomSettingResponse(room);

Expand All @@ -286,9 +306,12 @@ public void reconnectSession(

PlayerListResponse playerListResponse = toPlayerListResponse(room);

messageSender.send(destination, MessageType.ROOM_SETTING, roomSettingResponse);
messageSender.send(destination, MessageType.GAME_SETTING, gameSettingResponse);
messageSender.send(destination, MessageType.PLAYER_LIST, playerListResponse);
messageSender.sendPersonal(
userDestination, MessageType.ROOM_SETTING, roomSettingResponse, principal);
messageSender.sendPersonal(
userDestination, MessageType.PLAYER_LIST, playerListResponse, principal);
messageSender.sendPersonal(
userDestination, MessageType.GAME_SETTING, gameSettingResponse, principal);
}
}

Expand Down Expand Up @@ -362,4 +385,8 @@ private void removePlayer(Room room, String sessionId, Player removePlayer) {
room.removeSessionId(sessionId);
room.removeValidatedUserId(removePlayer.getId());
}

private String getUserDestination() {
return "/queue";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ public void startTimer(Room room, int delaySec) {
private void handleTimeout(Room room) {
String destination = getDestination(room.getId());

messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.QUESTION_RESULT,
toQuestionResultResponse(NONE_CORRECT_USER, room.getCurrentQuestion().getAnswer()));
messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.SYSTEM_NOTICE,
ofPlayerEvent(NONE_CORRECT_USER, RoomEventType.TIMEOUT));
Expand All @@ -64,7 +64,7 @@ private void handleTimeout(Room room) {
room.increaseCurrentRound();

startTimer(room, CONTINUE_DELAY);
messageSender.send(
messageSender.sendBroadcast(
destination,
MessageType.QUESTION_START,
toQuestionStartResponse(room, CONTINUE_DELAY));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public enum MessageType {
CHAT,
QUESTION_RESULT,
RANK_UPDATE,
EXIT_SUCCESS,
QUESTION_START
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public enum RoomEventType {
END(null),
CORRECT_ANSWER(SystemNoticeMessage.CORRECT_ANSWER),
TIMEOUT(SystemNoticeMessage.TIMEOUT),
RECONNECT(SystemNoticeMessage.RECONNECT);
RECONNECT(SystemNoticeMessage.RECONNECT),
RECONNECT_PRIVATE_NOTICE(SystemNoticeMessage.RECONNECT_PRIVATE_NOTICE);

private final SystemNoticeMessage systemMessage;

Expand All @@ -17,7 +18,7 @@ public enum RoomEventType {

public String getMessage(String nickname) {

if (this == TIMEOUT) {
if (this == TIMEOUT || this == RECONNECT_PRIVATE_NOTICE) {
return systemMessage.getMessage();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ public enum SystemNoticeMessage {
EXIT(" 님이 퇴장하셨습니다"),
CORRECT_ANSWER(" 님 정답입니다 !"),
TIMEOUT("땡 ~ ⏰ 제한 시간 초과!"),
RECONNECT(" 님이 재연결 되었습니다.");
RECONNECT(" 님이 재연결 되었습니다. "),
RECONNECT_PRIVATE_NOTICE("⚠️다음 라운드부터 참여하실 수 있습니다");

private final String message;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ public void afterChange(Room room, MessageSender messageSender) {
PlayerListResponse response = toPlayerListResponse(room);

log.info(response.toString());
messageSender.send(destination, MessageType.PLAYER_LIST, response);
messageSender.sendBroadcast(destination, MessageType.PLAYER_LIST, response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.f1.backend.domain.game.dto.response;

public record ExitSuccessResponse(boolean success) {}
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ public void updateTimer(ScheduledFuture<?> timer) {
this.timer = timer;
}

public void removeSessionId(String sessionId) {
this.playerSessionMap.remove(sessionId);
public boolean removeSessionId(String sessionId) {
return this.playerSessionMap.remove(sessionId) != null;
}

public void removeValidatedUserId(Long userId) {
Expand Down Expand Up @@ -134,10 +134,7 @@ public boolean isExit(String sessionId) {
}

public boolean isLastPlayer(String sessionId) {
long connectedCount =
playerSessionMap.values().stream()
.filter(player -> player.getState() == ConnectionState.CONNECTED)
.count();
long connectedCount = playerSessionMap.size();
return connectedCount == 1 && playerSessionMap.containsKey(sessionId);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.f1.backend.domain.game.dto.MessageType;
import io.f1.backend.domain.game.dto.response.DefaultWebSocketResponse;
import io.f1.backend.domain.user.dto.UserPrincipal;

import lombok.RequiredArgsConstructor;

Expand All @@ -14,8 +15,14 @@ public class MessageSender {

private final SimpMessagingTemplate messagingTemplate;

public <T> void send(String destination, MessageType type, T message) {
public <T> void sendBroadcast(String destination, MessageType type, T message) {
messagingTemplate.convertAndSend(
destination, new DefaultWebSocketResponse<>(type, message));
}

public <T> void sendPersonal(
String destination, MessageType type, T message, UserPrincipal principal) {
messagingTemplate.convertAndSendToUser(
principal.getName(), destination, new DefaultWebSocketResponse<>(type, message));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public void handleUserDisconnect(String sessionId, UserPrincipal principal) {
/* 재연결 실패 */
if (sessionId.equals(userIdSession.get(userId))) {
roomService.exitIfNotPlaying(roomId, sessionId, principal);
// 메세지 응답 추가
}
removeSession(sessionId, userId);
},
Expand Down
3 changes: 1 addition & 2 deletions backend/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,4 @@ server:
same-site: None
secure: true
http-only: true
timeout: ${SESSION_TIMEOUT}

timeout: ${SESSION_TIMEOUT}