1313import static io .f1 .backend .global .util .SecurityUtils .getCurrentUserNickname ;
1414
1515import io .f1 .backend .domain .game .dto .ChatMessage ;
16+ import io .f1 .backend .domain .game .dto .MessageType ;
1617import io .f1 .backend .domain .game .dto .RoomEventType ;
17- import io .f1 .backend .domain .game .dto .RoomExitData ;
18- import io .f1 .backend .domain .game .dto .RoomInitialData ;
19- import io .f1 .backend .domain .game .dto .RoundResult ;
2018import io .f1 .backend .domain .game .dto .request .RoomCreateRequest ;
2119import io .f1 .backend .domain .game .dto .request .RoomValidationRequest ;
2220import io .f1 .backend .domain .game .dto .response .GameSettingResponse ;
3230import io .f1 .backend .domain .game .model .RoomSetting ;
3331import io .f1 .backend .domain .game .model .RoomState ;
3432import io .f1 .backend .domain .game .store .RoomRepository ;
33+ import io .f1 .backend .domain .game .websocket .MessageSender ;
3534import io .f1 .backend .domain .question .entity .Question ;
3635import io .f1 .backend .domain .quiz .app .QuizService ;
3736import io .f1 .backend .domain .quiz .dto .QuizMinData ;
3837import io .f1 .backend .domain .quiz .entity .Quiz ;
3938import io .f1 .backend .domain .user .dto .UserPrincipal ;
4039import io .f1 .backend .global .exception .CustomException ;
4140import io .f1 .backend .global .exception .errorcode .RoomErrorCode ;
42-
43- import lombok .RequiredArgsConstructor ;
44- import lombok .extern .slf4j .Slf4j ;
45-
46- import org .springframework .context .ApplicationEventPublisher ;
47- import org .springframework .stereotype .Service ;
48-
4941import java .util .List ;
5042import java .util .Map ;
5143import java .util .Optional ;
5244import java .util .concurrent .ConcurrentHashMap ;
5345import java .util .concurrent .atomic .AtomicLong ;
46+ import lombok .RequiredArgsConstructor ;
47+ import lombok .extern .slf4j .Slf4j ;
48+ import org .springframework .context .ApplicationEventPublisher ;
49+ import org .springframework .stereotype .Service ;
5450
5551@ Slf4j
5652@ Service
@@ -62,6 +58,7 @@ public class RoomService {
6258 private final AtomicLong roomIdGenerator = new AtomicLong (0 );
6359 private final ApplicationEventPublisher eventPublisher ;
6460 private final Map <Long , Object > roomLocks = new ConcurrentHashMap <>();
61+ private final MessageSender messageSender ;
6562 private static final String PENDING_SESSION_ID = "PENDING_SESSION_ID" ;
6663
6764 public RoomCreateResponse saveRoom (RoomCreateRequest request ) {
@@ -108,16 +105,16 @@ public void enterRoom(RoomValidationRequest request) {
108105 }
109106
110107 if (room .getRoomSetting ().locked ()
111- && !room .getRoomSetting ().password ().equals (request .password ())) {
108+ && !room .getRoomSetting ().password ().equals (request .password ())) {
112109 throw new CustomException (RoomErrorCode .WRONG_PASSWORD );
113110 }
114111
115112 room .getUserIdSessionMap ().put (getCurrentUserId (), PENDING_SESSION_ID );
116113 }
117114 }
118115
119- public RoomInitialData initializeRoomSocket (
120- Long roomId , String sessionId , UserPrincipal principal ) {
116+ public void initializeRoomSocket (
117+ Long roomId , String sessionId , UserPrincipal principal ) {
121118
122119 Room room = findRoom (roomId );
123120
@@ -143,18 +140,26 @@ public RoomInitialData initializeRoomSocket(
143140 Quiz quiz = quizService .getQuizWithQuestionsById (quizId );
144141
145142 GameSettingResponse gameSettingResponse =
146- toGameSettingResponse (room .getGameSetting (), quiz );
143+ toGameSettingResponse (room .getGameSetting (), quiz );
147144
148145 PlayerListResponse playerListResponse = toPlayerListResponse (room );
149146
150147 SystemNoticeResponse systemNoticeResponse =
151- ofPlayerEvent (player .getNickname (), RoomEventType .ENTER );
152-
153- return new RoomInitialData (
154- roomSettingResponse , gameSettingResponse , playerListResponse , systemNoticeResponse );
148+ ofPlayerEvent (player .getNickname (), RoomEventType .ENTER );
149+
150+ String destination = getDestination (roomId );
151+
152+ messageSender .send (
153+ destination , MessageType .ROOM_SETTING , roomSettingResponse );
154+ messageSender .send (
155+ destination , MessageType .GAME_SETTING , gameSettingResponse );
156+ messageSender .send (
157+ destination , MessageType .PLAYER_LIST , playerListResponse );
158+ messageSender .send (
159+ destination , MessageType .SYSTEM_NOTICE , systemNoticeResponse );
155160 }
156161
157- public RoomExitData exitRoom (Long roomId , String sessionId , UserPrincipal principal ) {
162+ public void exitRoom (Long roomId , String sessionId , UserPrincipal principal ) {
158163
159164 Object lock = roomLocks .computeIfAbsent (roomId , k -> new Object ());
160165
@@ -165,7 +170,8 @@ public RoomExitData exitRoom(Long roomId, String sessionId, UserPrincipal princi
165170
166171 /* 방 삭제 */
167172 if (isLastPlayer (room , sessionId )) {
168- return removeRoom (room );
173+ removeRoom (room );
174+ return ;
169175 }
170176
171177 /* 방장 변경 */
@@ -177,67 +183,78 @@ public RoomExitData exitRoom(Long roomId, String sessionId, UserPrincipal princi
177183 removePlayer (room , sessionId , removePlayer );
178184
179185 SystemNoticeResponse systemNoticeResponse =
180- ofPlayerEvent (removePlayer .nickname , RoomEventType .EXIT );
186+ ofPlayerEvent (removePlayer .nickname , RoomEventType .EXIT );
181187
182188 PlayerListResponse playerListResponse = toPlayerListResponse (room );
183189
184- return new RoomExitData (playerListResponse , systemNoticeResponse , false );
190+ String destination = getDestination (roomId );
191+
192+ messageSender .send (
193+ destination , MessageType .PLAYER_LIST , playerListResponse );
194+ messageSender .send (
195+ destination , MessageType .SYSTEM_NOTICE , systemNoticeResponse );
196+
185197 }
186198 }
187199
188- public PlayerListResponse handlePlayerReady (Long roomId , String sessionId ) {
200+ public void handlePlayerReady (Long roomId , String sessionId ) {
189201 Player player =
190- roomRepository
191- .findPlayerInRoomBySessionId (roomId , sessionId )
192- .orElseThrow (() -> new CustomException (RoomErrorCode .PLAYER_NOT_FOUND ));
202+ roomRepository
203+ .findPlayerInRoomBySessionId (roomId , sessionId )
204+ .orElseThrow (() -> new CustomException (RoomErrorCode .PLAYER_NOT_FOUND ));
193205
194206 player .toggleReady ();
195207
196208 Room room = findRoom (roomId );
197209
198- return toPlayerListResponse (room );
210+ String destination = getDestination (roomId );
211+
212+ messageSender .send (destination , MessageType .PLAYER_LIST , toPlayerListResponse (room ));
213+
199214 }
200215
201216 public RoomListResponse getAllRooms () {
202217 List <Room > rooms = roomRepository .findAll ();
203218 List <RoomResponse > roomResponses =
204- rooms .stream ()
205- .map (
206- room -> {
207- Long quizId = room .getGameSetting ().getQuizId ();
208- Quiz quiz = quizService .getQuizWithQuestionsById (quizId );
209-
210- return toRoomResponse (room , quiz );
211- })
212- .toList ();
219+ rooms .stream ()
220+ .map (
221+ room -> {
222+ Long quizId = room .getGameSetting ().getQuizId ();
223+ Quiz quiz = quizService .getQuizWithQuestionsById (quizId );
224+
225+ return toRoomResponse (room , quiz );
226+ })
227+ .toList ();
213228 return new RoomListResponse (roomResponses );
214229 }
215230
216231 // todo 동시성적용
217- public RoundResult chat (Long roomId , String sessionId , ChatMessage chatMessage ) {
232+ public void chat (Long roomId , String sessionId , ChatMessage chatMessage ) {
218233 Room room = findRoom (roomId );
219234
235+ String destination = getDestination (roomId );
236+
237+ messageSender .send (destination , MessageType .CHAT , chatMessage );
238+
220239 if (!room .isPlaying ()) {
221- return buildResultOnlyChat ( chatMessage ) ;
240+ return ;
222241 }
223242
224243 Question currentQuestion = room .getCurrentQuestion ();
225244
226245 String answer = currentQuestion .getAnswer ();
227246
228- if (!answer .equals (chatMessage .message ())) {
229- return buildResultOnlyChat (chatMessage );
230- }
231-
232- room .increasePlayerCorrectCount (sessionId );
247+ if (answer .equals (chatMessage .message ())) {
248+ room .increasePlayerCorrectCount (sessionId );
233249
234- return RoundResult .builder ()
235- .questionResult (
236- toQuestionResultResponse (currentQuestion .getId (), chatMessage , answer ))
237- .rankUpdate (toRankUpdateResponse (room ))
238- .systemNotice (ofPlayerEvent (chatMessage .nickname (), RoomEventType .ENTER ))
239- .chat (chatMessage )
240- .build ();
250+ messageSender .send (
251+ destination , MessageType .QUESTION_RESULT ,
252+ toQuestionResultResponse (currentQuestion .getId (), chatMessage , answer ));
253+ messageSender .send (destination , MessageType .RANK_UPDATE , toRankUpdateResponse (room ));
254+ messageSender .send (
255+ destination , MessageType .SYSTEM_NOTICE ,
256+ ofPlayerEvent (chatMessage .nickname (), RoomEventType .ENTER ));
257+ }
241258 }
242259
243260 private Player getRemovePlayer (Room room , String sessionId , UserPrincipal principal ) {
@@ -259,35 +276,34 @@ private Player createPlayer() {
259276
260277 private Room findRoom (Long roomId ) {
261278 return roomRepository
262- .findRoom (roomId )
263- .orElseThrow (() -> new CustomException (RoomErrorCode .ROOM_NOT_FOUND ));
279+ .findRoom (roomId )
280+ .orElseThrow (() -> new CustomException (RoomErrorCode .ROOM_NOT_FOUND ));
264281 }
265282
266283 private boolean isLastPlayer (Room room , String sessionId ) {
267284 Map <String , Player > playerSessionMap = room .getPlayerSessionMap ();
268285 return playerSessionMap .size () == 1 && playerSessionMap .containsKey (sessionId );
269286 }
270287
271- private RoomExitData removeRoom (Room room ) {
288+ private void removeRoom (Room room ) {
272289 Long roomId = room .getId ();
273290 roomRepository .removeRoom (roomId );
274291 roomLocks .remove (roomId );
275292 log .info ("{}번 방 삭제" , roomId );
276- return RoomExitData .builder ().removedRoom (true ).build ();
277293 }
278294
279295 private void changeHost (Room room , String hostSessionId ) {
280296 Map <String , Player > playerSessionMap = room .getPlayerSessionMap ();
281297
282298 Optional <String > nextHostSessionId =
283- playerSessionMap .keySet ().stream ()
284- .filter (key -> !key .equals (hostSessionId ))
285- .findFirst ();
299+ playerSessionMap .keySet ().stream ()
300+ .filter (key -> !key .equals (hostSessionId ))
301+ .findFirst ();
286302
287303 Player nextHost =
288- playerSessionMap .get (
289- nextHostSessionId .orElseThrow (
290- () -> new CustomException (RoomErrorCode .SOCKET_SESSION_NOT_FOUND )));
304+ playerSessionMap .get (
305+ nextHostSessionId .orElseThrow (
306+ () -> new CustomException (RoomErrorCode .SOCKET_SESSION_NOT_FOUND )));
291307
292308 room .updateHost (nextHost );
293309 log .info ("user_id:{} 방장 변경 완료 " , nextHost .getId ());
@@ -298,7 +314,8 @@ private void removePlayer(Room room, String sessionId, Player removePlayer) {
298314 room .removeSessionId (sessionId );
299315 }
300316
301- private RoundResult buildResultOnlyChat (ChatMessage chatMessage ) {
302- return RoundResult .builder ().chat (chatMessage ).build ();
317+
318+ private String getDestination (Long roomId ) {
319+ return "/sub/room/" + roomId ;
303320 }
304321}
0 commit comments