From 0e343812d3bbe9389b569e769f8ed6232df3911d Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Tue, 23 Dec 2025 19:55:22 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=EB=B0=A9=EC=9E=A5=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20DAO=20=EA=B5=AC=ED=98=84=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/room/dao/RoomDAO.java | 7 +++++++ src/main/java/room/dao/RoomDAOImpl.java | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/main/java/room/dao/RoomDAO.java b/src/main/java/room/dao/RoomDAO.java index 6351c4b..13495fe 100644 --- a/src/main/java/room/dao/RoomDAO.java +++ b/src/main/java/room/dao/RoomDAO.java @@ -22,4 +22,11 @@ RoomDTO createRoom( */ String getHostUserId(String roomId) throws Exception; + /** + * roomId로 방장 userId 조회 + * @param roomId 방 ID + * @return hostUserId (없으면 null) + */ + String findHostUserIdByRoomId(String roomId) throws Exception; + } \ No newline at end of file diff --git a/src/main/java/room/dao/RoomDAOImpl.java b/src/main/java/room/dao/RoomDAOImpl.java index 77ec757..15cc30a 100644 --- a/src/main/java/room/dao/RoomDAOImpl.java +++ b/src/main/java/room/dao/RoomDAOImpl.java @@ -169,6 +169,29 @@ public String getHostUserId(String roomId) throws Exception { } } + @Override + public String findHostUserIdByRoomId(String roomId) throws Exception { + + String sql = """ + SELECT host_user_id + FROM room + WHERE id = ? + """; + + try ( + Connection conn = DB.getConnection(); + PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, roomId); + + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return rs.getString("host_user_id"); + } + return null; + } + } + } + private RoomDTO mapToRoom(ResultSet rs) throws SQLException { return RoomDTO.builder() .id(rs.getString("id")) From 09e0b18694ecfc7a4de69559663dc8dde6515c08 Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Tue, 23 Dec 2025 20:23:19 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=A9=EC=9E=A5=20ID=20=EC=84=B8=EC=85=98=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EC=8B=9C=EC=9E=91=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=91=9C=EC=8B=9C=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/lobby/controller/CreateRoomController.java | 2 ++ src/main/webapp/WEB-INF/views/room.jsp | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/lobby/controller/CreateRoomController.java b/src/main/java/lobby/controller/CreateRoomController.java index 047e43c..015ee61 100644 --- a/src/main/java/lobby/controller/CreateRoomController.java +++ b/src/main/java/lobby/controller/CreateRoomController.java @@ -60,6 +60,8 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) String roomId = roomResult.getId(); + session.setAttribute("hostUserId", hostUserId); + roomPlayerDAO.enterIfAbsent(roomResult.getId(), hostUserId); LobbyWebSocket.broadcastRoomList(); diff --git a/src/main/webapp/WEB-INF/views/room.jsp b/src/main/webapp/WEB-INF/views/room.jsp index e8bbada..1a90f19 100644 --- a/src/main/webapp/WEB-INF/views/room.jsp +++ b/src/main/webapp/WEB-INF/views/room.jsp @@ -49,16 +49,18 @@
-

👥 참가자

+

👥 참가자

    -
    + + +

    💬 채팅

    From 78e7ef8d97a1654100ae7476ae9b28592ed0d809 Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Tue, 23 Dec 2025 23:55:51 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EB=B0=A9=EC=9E=A5=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=9B=B9=EC=86=8C=EC=BC=93=20=EC=9D=B4=EB=B2=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B2=98=EB=A6=AC=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room/controller/ViewRoomController.java | 11 +++++++ src/main/java/room/ws/RoomWebSocket.java | 4 +-- .../java/room/ws/RoomWebSocketService.java | 29 +++++++++++++++++-- src/main/webapp/WEB-INF/views/lobby.jsp | 2 -- src/main/webapp/WEB-INF/views/room.jsp | 1 + src/main/webapp/static/room/room.js | 28 ++++++++++++++++++ 6 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/main/java/room/controller/ViewRoomController.java b/src/main/java/room/controller/ViewRoomController.java index ce03157..60ee2a5 100644 --- a/src/main/java/room/controller/ViewRoomController.java +++ b/src/main/java/room/controller/ViewRoomController.java @@ -7,14 +7,20 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import room.dao.RoomDAO; +import room.dao.RoomDAOImpl; @WebServlet("/room") public class ViewRoomController extends HttpServlet { private static final long serialVersionUID = 1L; + private final RoomDAO roomDAO = new RoomDAOImpl(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try { String roomId = request.getParameter("roomId"); String playType = request.getParameter("playType"); @@ -26,6 +32,11 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) request.setAttribute("roomId", roomId); request.setAttribute("playType", playType); + HttpSession session = request.getSession(false); + String userId = (session == null) ? null : (String)session.getAttribute("loginUserId"); + String hostUserId = roomDAO.findHostUserIdByRoomId(roomId); + session.setAttribute("hostUserId", hostUserId); + session.setAttribute("userId", userId); request.getRequestDispatcher("/WEB-INF/views/room.jsp").forward(request, response); return; diff --git a/src/main/java/room/ws/RoomWebSocket.java b/src/main/java/room/ws/RoomWebSocket.java index df7b4f2..8ae79e9 100644 --- a/src/main/java/room/ws/RoomWebSocket.java +++ b/src/main/java/room/ws/RoomWebSocket.java @@ -148,7 +148,7 @@ public void onMessage(Session session, String text) { case "ROOM_EXIT": { String roomId = sessionContext.getRoomId(session); - service.onExit(session, roomId); + service.onExit(session, roomId, "ROOM_EXIT"); sessionContext.leaveRoom(session); service.sendIfOpen(session, "ROOM_EXIT", Map.of()); @@ -215,7 +215,7 @@ public void onClose(Session session, CloseReason reason) { String result = roomService.exitAndHandleHost(roomId, userId); System.out.println("[RoomWS][EXIT] roomId=" + roomId + " userId=" + userId + " result=" + result); - service.onExit(session, roomId); + service.onExit(session, roomId, result); LobbyWebSocket.broadcastRoomList(); } } catch (Exception e) { diff --git a/src/main/java/room/ws/RoomWebSocketService.java b/src/main/java/room/ws/RoomWebSocketService.java index 894a2f6..ff2ac70 100644 --- a/src/main/java/room/ws/RoomWebSocketService.java +++ b/src/main/java/room/ws/RoomWebSocketService.java @@ -9,6 +9,8 @@ import com.google.gson.Gson; +import room.dao.RoomDAO; +import room.dao.RoomDAOImpl; import room.dao.RoomPlayerDAO; import room.dao.RoomPlayerDAOImpl; import room.dto.RoomPlayerDTO; @@ -25,6 +27,7 @@ public class RoomWebSocketService { private static final SessionContext sessionContext = SessionContext.getInstance(); private static final RoomSessionRegistry roomRegistry = RoomSessionRegistry.getInstance(); private final RoomPlayerDAO roomPlayerDao = new RoomPlayerDAOImpl(); + private final RoomDAO roomDao = new RoomDAOImpl(); public void sendIfOpen(Session s, String type, Map payload) { if (s == null || !s.isOpen()) @@ -74,22 +77,33 @@ public void onChat(Session session, String roomId, String text) { "text", text)); } - public void onExit(Session session, String roomId) { + public void onExit(Session session, String roomId, String result) { if (roomId == null || roomId.isBlank()) return; roomRegistry.leave(roomId, session); + if ("HOST_CHANGE".equals(result)) { + String hostUserId; + try { + hostUserId = roomDao.getHostUserId(roomId); + broadcastHostChanged(roomId, hostUserId); + } catch (Exception e) { + e.printStackTrace(); + } + + } broadcast(roomId, "USER_EXIT", Map.of( "userId", sessionContext.getUserId(session), "nickname", sessionContext.getNickname(session))); + } /** @OnClose/@OnError 최종 정리 */ public void cleanup(Session session) { String roomId = sessionContext.getRoomId(session); if (roomId != null && !roomId.isBlank()) { - onExit(session, roomId); + onExit(session, roomId, null); sessionContext.leaveRoom(session); } else { roomRegistry.removeFromAnyRoom(session); @@ -111,6 +125,17 @@ public void broadcastGameStart(String roomId, String gameId, String playType) { broadcast(roomId, "GAME_START", payload); } + public void broadcastHostChanged(String roomId, String hostUserId) { + if (roomId == null || roomId.isBlank()) + return; + + Map payload = new HashMap<>(); + payload.put("roomId", roomId); + payload.put("hostUserId", hostUserId); + + broadcast(roomId, "HOST_CHANGE", payload); + } + private void broadcast(String roomId, String type, Map payload) { Set sessions = roomRegistry.getSessions(roomId); for (Session s : sessions) { diff --git a/src/main/webapp/WEB-INF/views/lobby.jsp b/src/main/webapp/WEB-INF/views/lobby.jsp index a659d20..ce9fa24 100644 --- a/src/main/webapp/WEB-INF/views/lobby.jsp +++ b/src/main/webapp/WEB-INF/views/lobby.jsp @@ -44,10 +44,8 @@ -
    -

    게임 방 목록

    참여할 게임을 선택하세요

    diff --git a/src/main/webapp/WEB-INF/views/room.jsp b/src/main/webapp/WEB-INF/views/room.jsp index 1a90f19..388d897 100644 --- a/src/main/webapp/WEB-INF/views/room.jsp +++ b/src/main/webapp/WEB-INF/views/room.jsp @@ -16,6 +16,7 @@ data-room-name="" data-play-type="" data-host-user-id="" + data-user-id="" >
    diff --git a/src/main/webapp/static/room/room.js b/src/main/webapp/static/room/room.js index 433d1d6..6b0103d 100644 --- a/src/main/webapp/static/room/room.js +++ b/src/main/webapp/static/room/room.js @@ -2,6 +2,9 @@ const pageEl = document.querySelector("#room-page"); const roomId = pageEl?.dataset?.roomId || ""; const roomName = pageEl?.dataset?.roomName || ""; + const userId = pageEl?.dataset?.userId || ""; + + const wsStatus = document.querySelector("#ws-status"); const chatInput = document.querySelector("#chat-input"); // input @@ -180,6 +183,31 @@ appendSystemLog("방에서 나갔습니다."); break; } + + case "HOST_CHANGE": { + appendSystemLog("방장이 변경되었습니다."); + const p = msg.payload; + const page = document.querySelector("#room-page"); + const roomId = page.dataset.roomId; + const playType = page.dataset.playType; + if (p.hostUserId === userId) { + const form = document.createElement("form"); + form.id = "start-form"; + form.method = "post"; + form.action = `/game/start?roomId=${encodeURIComponent(roomId)}&playType=${encodeURIComponent(playType)}`; + + const btn = document.createElement("button"); + btn.type = "submit"; + btn.id = "btn-start"; + btn.className = "btn-start"; + btn.textContent = "🎯 시작하기"; + + form.appendChild(btn); + document.querySelector(".side-nav")?.appendChild(form); + } + console.log(p); + break; + } case "ERROR": { handleError(msg); From a3924702709ff8cedb85ddc37544493408fba0ed Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Wed, 24 Dec 2025 01:06:17 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91=20=EC=A0=84=20=EB=B0=A9=20=EC=9D=B8=EC=9B=90=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../game/controller/GameStartController.java | 1 + .../java/room/controller/RoomController.java | 144 ++++++++++++++++++ .../java/room/dto/RoomActiveCountDTO.java | 11 ++ src/main/webapp/WEB-INF/views/room.jsp | 6 +- src/main/webapp/static/room/room.js | 113 ++++++++------ 5 files changed, 226 insertions(+), 49 deletions(-) create mode 100644 src/main/java/room/controller/RoomController.java create mode 100644 src/main/java/room/dto/RoomActiveCountDTO.java diff --git a/src/main/java/game/controller/GameStartController.java b/src/main/java/game/controller/GameStartController.java index 9712cc2..41f17de 100644 --- a/src/main/java/game/controller/GameStartController.java +++ b/src/main/java/game/controller/GameStartController.java @@ -59,6 +59,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response) response.sendError(HttpServletResponse.SC_FORBIDDEN, "게임 시작 권한이 없습니다. (host만 가능)"); return; } + int updated = roomPlayerDao.updatePlayersToInGame(roomId); System.out.println("[GameStart] roomId=" + roomId + " updatedPlayers=" + updated); diff --git a/src/main/java/room/controller/RoomController.java b/src/main/java/room/controller/RoomController.java new file mode 100644 index 0000000..ccd790b --- /dev/null +++ b/src/main/java/room/controller/RoomController.java @@ -0,0 +1,144 @@ +package room.controller; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import com.google.gson.Gson; + +import room.dao.RoomPlayerDAO; +import room.dao.RoomPlayerDAOImpl; +import room.dto.RoomActiveCountDTO; + +@WebServlet("/room/*") +public class RoomController extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private final Gson gson = new Gson(); + private final RoomPlayerDAO roomPlayerDAO = new RoomPlayerDAOImpl(); + + @FunctionalInterface + private interface Handler { + void handle(HttpServletRequest req, HttpServletResponse res, String userId) throws Exception; + } + + private final Map getHandlers = new HashMap<>(); + + @Override + public void init() { + getHandlers.put("count", this::handleGetCount); + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse res) + throws ServletException, IOException { + + String action = getAction(req); + if (action == null) { + sendJson(res, 400, ApiError.of("잘못된 요청입니다.")); + return; + } + + String userId = getLoginUserId(req); + if (userId == null || userId.isBlank()) { + sendJson(res, 401, ApiError.of("로그인이 필요합니다.")); + return; + } + + Handler handler = getHandlers.get(action); + if (handler == null) { + sendJson(res, 404, ApiError.of("존재하지 않는 API입니다.")); + return; + } + + try { + handler.handle(req, res, userId); + } catch (Exception e) { + e.printStackTrace(); + sendJson(res, 500, ApiError.of("서버 오류가 발생했습니다.")); + } + } + + /** + * GET /room/count?roomId= + * 응답: { ok:true, data:{ roomId, totalCount, activeCount } } + */ + private void handleGetCount(HttpServletRequest req, HttpServletResponse res, String userId) throws Exception { + String roomId = req.getParameter("roomId"); + if (roomId == null || roomId.isBlank()) { + sendJson(res, 400, ApiError.of("roomId가 필요합니다.")); + return; + } + int activeCount = roomPlayerDAO.countActivePlayers(roomId); + RoomActiveCountDTO dto = new RoomActiveCountDTO(roomId, activeCount); + sendJson(res, 200, ApiSuccess.of(dto)); + } + + private String getAction(HttpServletRequest req) { + String pathInfo = req.getPathInfo(); + if (pathInfo == null || "/".equals(pathInfo)) + return null; + return pathInfo.substring(1); + } + + private String getLoginUserId(HttpServletRequest req) { + HttpSession session = req.getSession(false); + return (session == null) ? null : (String)session.getAttribute("loginUserId"); + } + + private void sendJson(HttpServletResponse res, int status, Object body) throws IOException { + res.setStatus(status); + res.setContentType("application/json; charset=UTF-8"); + res.getWriter().write(gson.toJson(body)); + } + + private static class ApiSuccess { + private final boolean ok = true; + private final T data; + + private ApiSuccess(T data) { + this.data = data; + } + + public static ApiSuccess of(T data) { + return new ApiSuccess<>(data); + } + + public boolean isOk() { + return ok; + } + + public T getData() { + return data; + } + } + + private static class ApiError { + private final boolean ok = false; + private final String message; + + private ApiError(String message) { + this.message = message; + } + + public static ApiError of(String message) { + return new ApiError(message); + } + + public boolean isOk() { + return ok; + } + + public String getMessage() { + return message; + } + } +} diff --git a/src/main/java/room/dto/RoomActiveCountDTO.java b/src/main/java/room/dto/RoomActiveCountDTO.java new file mode 100644 index 0000000..f0d50b3 --- /dev/null +++ b/src/main/java/room/dto/RoomActiveCountDTO.java @@ -0,0 +1,11 @@ +package room.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class RoomActiveCountDTO { + private String roomId; + private int activeCount; +} diff --git a/src/main/webapp/WEB-INF/views/room.jsp b/src/main/webapp/WEB-INF/views/room.jsp index 388d897..1ecad5c 100644 --- a/src/main/webapp/WEB-INF/views/room.jsp +++ b/src/main/webapp/WEB-INF/views/room.jsp @@ -54,13 +54,9 @@
      -
      - -
      diff --git a/src/main/webapp/static/room/room.js b/src/main/webapp/static/room/room.js index 6b0103d..926d422 100644 --- a/src/main/webapp/static/room/room.js +++ b/src/main/webapp/static/room/room.js @@ -3,6 +3,7 @@ const roomId = pageEl?.dataset?.roomId || ""; const roomName = pageEl?.dataset?.roomName || ""; const userId = pageEl?.dataset?.userId || ""; + const playType = pageEl.dataset.playType || ""; @@ -185,28 +186,24 @@ } case "HOST_CHANGE": { - appendSystemLog("방장이 변경되었습니다."); - const p = msg.payload; - const page = document.querySelector("#room-page"); - const roomId = page.dataset.roomId; - const playType = page.dataset.playType; - if (p.hostUserId === userId) { - const form = document.createElement("form"); - form.id = "start-form"; - form.method = "post"; - form.action = `/game/start?roomId=${encodeURIComponent(roomId)}&playType=${encodeURIComponent(playType)}`; + appendSystemLog("방장이 변경되었습니다."); + const p = msg.payload; - const btn = document.createElement("button"); - btn.type = "submit"; - btn.id = "btn-start"; - btn.className = "btn-start"; - btn.textContent = "🎯 시작하기"; + if (p.hostUserId !== userId) break; - form.appendChild(btn); - document.querySelector(".side-nav")?.appendChild(form); - } - console.log(p); + if (document.querySelector("#btn-start")) break; + + const btn = document.createElement("button"); + btn.type = "button"; + btn.id = "btn-start"; + btn.className = "btn-start"; + btn.textContent = "🎯 시작하기"; + + btn.addEventListener("click", startButtonClick); + + document.querySelector(".side-nav")?.appendChild(btn); break; + } case "ERROR": { @@ -253,32 +250,60 @@ location.href = "/lobby"; }); - const startForm = document.querySelector("#start-form"); - startForm?.addEventListener("submit", async (e) => { - e.preventDefault(); - - const formData = new FormData(startForm); - const params = new URLSearchParams(formData); - - try { - const response = await fetch(startForm.action, { - method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" }, - body: params, - }); - - if (!response.ok) { - const text = await response.text(); - alert(`게임 시작 실패: ${text}`); - } - // 성공 시: 서버가 WS로 GAME_START를 보내면 - // room.js의 GAME_START 핸들러가 페이지 이동 처리함 :contentReference[oaicite:2]{index=2} - } catch (err) { - console.error("게임 시작 요청 실패:", err); - alert("게임 시작 요청 중 오류가 발생했습니다."); - } - }); +const btnStart = document.querySelector("#btn-start"); + btnStart?.addEventListener("click", async () => { + startButtonClick() + }); + + async function startButtonClick() { + const page = document.querySelector("#room-page"); + const roomId = page.dataset.roomId; + const playType = page.dataset.playType; + const contextPath = page.dataset.contextPath || ""; + + try { + const countRes = await fetch( + `${contextPath}/room/count?roomId=${encodeURIComponent(roomId)}`, + { method: "GET", credentials: "same-origin" } + ); + const countResult = await countRes.json(); + + if (!countResult.ok) { + alert(countResult.message || "인원 수 조회 실패"); + return; + } + + const { activeCount } = countResult.data; + const minPlayers = playType === "1" ? 4 : 2; + + if (activeCount < minPlayers) { + alert(`아직 인원이 부족합니다. (최소 ${minPlayers}명 필요)`); + return; + } + + const body = new URLSearchParams(); + body.set("roomId", roomId); + body.set("playType", playType); + + const startRes = await fetch(`${contextPath}/game/start`, { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" }, + body, + credentials: "same-origin", + }); + + if (!startRes.ok) { + const text = await startRes.text(); + alert(`게임 시작 실패: ${text}`); + return; + } + + } catch (err) { + console.error(err); + alert("게임 시작 요청 중 오류가 발생했습니다."); + } + } /* IME 조합 상태 추적 (한글 뒷글자 중복 방지) */ let isComposing = false; chatInput?.addEventListener("compositionstart", () => { From b3060145a415ec3fdbb203a899daa4ca8cc42bbd Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Wed, 24 Dec 2025 01:22:53 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20Room=20Controller=20=EC=9D=B8?= =?UTF-8?q?=EC=9B=90=20=EC=A1=B0=ED=9A=8C=20=EC=A3=BC=EC=84=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/room/controller/RoomController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/room/controller/RoomController.java b/src/main/java/room/controller/RoomController.java index ccd790b..86bee1b 100644 --- a/src/main/java/room/controller/RoomController.java +++ b/src/main/java/room/controller/RoomController.java @@ -69,7 +69,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res) /** * GET /room/count?roomId= - * 응답: { ok:true, data:{ roomId, totalCount, activeCount } } + * 응답: { ok:true, data:{ roomId, activeCount } } */ private void handleGetCount(HttpServletRequest req, HttpServletResponse res, String userId) throws Exception { String roomId = req.getParameter("roomId"); From 17c29984a7315c540fc182b0761c58e1afa9daa1 Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Wed, 24 Dec 2025 01:32:17 +0900 Subject: [PATCH 6/7] =?UTF-8?q?fix:=20hostUserId,=20session=20nullPointer?= =?UTF-8?q?=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/room/controller/ViewRoomController.java | 6 ++++-- src/main/java/room/ws/RoomWebSocketService.java | 4 +++- src/main/webapp/static/room/room.js | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/room/controller/ViewRoomController.java b/src/main/java/room/controller/ViewRoomController.java index 60ee2a5..6ab997f 100644 --- a/src/main/java/room/controller/ViewRoomController.java +++ b/src/main/java/room/controller/ViewRoomController.java @@ -24,17 +24,19 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) try { String roomId = request.getParameter("roomId"); String playType = request.getParameter("playType"); + HttpSession session = request.getSession(false); - if (roomId == null) { + if (playType == null || roomId == null || session == null) { response.sendRedirect("/lobby"); return; } request.setAttribute("roomId", roomId); request.setAttribute("playType", playType); - HttpSession session = request.getSession(false); + String userId = (session == null) ? null : (String)session.getAttribute("loginUserId"); String hostUserId = roomDAO.findHostUserIdByRoomId(roomId); + session.setAttribute("hostUserId", hostUserId); session.setAttribute("userId", userId); diff --git a/src/main/java/room/ws/RoomWebSocketService.java b/src/main/java/room/ws/RoomWebSocketService.java index ff2ac70..c5f1422 100644 --- a/src/main/java/room/ws/RoomWebSocketService.java +++ b/src/main/java/room/ws/RoomWebSocketService.java @@ -87,7 +87,9 @@ public void onExit(Session session, String roomId, String result) { String hostUserId; try { hostUserId = roomDao.getHostUserId(roomId); - broadcastHostChanged(roomId, hostUserId); + if (hostUserId != null) { + broadcastHostChanged(roomId, hostUserId); + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/webapp/static/room/room.js b/src/main/webapp/static/room/room.js index 926d422..7a5fd8b 100644 --- a/src/main/webapp/static/room/room.js +++ b/src/main/webapp/static/room/room.js @@ -3,7 +3,6 @@ const roomId = pageEl?.dataset?.roomId || ""; const roomName = pageEl?.dataset?.roomName || ""; const userId = pageEl?.dataset?.userId || ""; - const playType = pageEl.dataset.playType || ""; From 30e850235a12c58e49d633341f7848eabd5954d9 Mon Sep 17 00:00:00 2001 From: gaeunnlee Date: Wed, 24 Dec 2025 01:38:56 +0900 Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20null=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20hostUserI?= =?UTF-8?q?d=20=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/room/controller/ViewRoomController.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/room/controller/ViewRoomController.java b/src/main/java/room/controller/ViewRoomController.java index 6ab997f..bbfb4a6 100644 --- a/src/main/java/room/controller/ViewRoomController.java +++ b/src/main/java/room/controller/ViewRoomController.java @@ -34,9 +34,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) request.setAttribute("roomId", roomId); request.setAttribute("playType", playType); - String userId = (session == null) ? null : (String)session.getAttribute("loginUserId"); + String userId = (String)session.getAttribute("loginUserId"); String hostUserId = roomDAO.findHostUserIdByRoomId(roomId); + if (hostUserId == null) { + response.sendRedirect("/lobby?error=host_not_found"); + return; + } + session.setAttribute("hostUserId", hostUserId); session.setAttribute("userId", userId);