diff --git a/apps/client/src/hooks/useAppFlow.ts b/apps/client/src/hooks/useAppFlow.ts index db815c9..2bcc332 100644 --- a/apps/client/src/hooks/useAppFlow.ts +++ b/apps/client/src/hooks/useAppFlow.ts @@ -57,6 +57,11 @@ setIsJoining(false); if (payload.reason === "full") { setJoinErrorMessage(`ルーム ${payload.roomId} は満員です`); + return; + } + + if (payload.reason === "duplicate") { + setJoinErrorMessage(`ルーム ${payload.roomId} への参加要求が重複しました`); } }; const handleGameStart = () => { diff --git a/apps/server/src/network/handlers/room/registerRoomHandlers.ts b/apps/server/src/network/handlers/room/registerRoomHandlers.ts index 33dd81c..7d7fbbf 100644 --- a/apps/server/src/network/handlers/room/registerRoomHandlers.ts +++ b/apps/server/src/network/handlers/room/registerRoomHandlers.ts @@ -43,7 +43,7 @@ publishRoomUpdate: roomPublisher.publishRoomUpdate, }); - // 満員拒否時はソケットのルーム参加状態を巻き戻す + // 参加拒否時は理由を通知する if (joinResult.status === "full") { socket.leave(roomId); roomPublisher.publishJoinRejected({ @@ -56,6 +56,20 @@ roomId, socketId: socket.id, }); + return; + } + + if (joinResult.status === "duplicate") { + roomPublisher.publishJoinRejected({ + roomId, + reason: "duplicate", + }); + logEvent("Network", { + event: "JOIN_ROOM", + result: "rejected_duplicate", + roomId, + socketId: socket.id, + }); } }); }; diff --git a/packages/shared/src/domains/room/room.type.ts b/packages/shared/src/domains/room/room.type.ts index 6226444..f69dcbd 100644 --- a/packages/shared/src/domains/room/room.type.ts +++ b/packages/shared/src/domains/room/room.type.ts @@ -25,7 +25,7 @@ } // ルーム参加拒否理由型 -export type JoinRoomRejectedReason = "full"; +export type JoinRoomRejectedReason = "full" | "duplicate"; // ルーム参加拒否通知ペイロード型 export interface JoinRoomRejectedPayload {