From a0d01f173111953867ef7345f5fe17a0366c5bb9 Mon Sep 17 00:00:00 2001 From: Jae-HyeokKim Date: Tue, 26 Aug 2025 10:07:01 +0900 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=B1=84=ED=8C=85=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=20=EB=A1=9C=EC=A7=81=20=EB=94=94=EB=B2=84=EA=B9=85=20?= =?UTF-8?q?(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/chat/bus/ChatRedisPublisher.java | 13 +++++++++---- .../controller/ChatMessagingController.java | 18 +++++++++--------- .../global/configuration/RedisConfig.java | 1 + .../global/redis/RedisSubscriber.java | 3 ++- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/bus/ChatRedisPublisher.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/bus/ChatRedisPublisher.java index ecc9272..0a714fe 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/bus/ChatRedisPublisher.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/bus/ChatRedisPublisher.java @@ -1,6 +1,7 @@ package likelion.mlb.backendProject.domain.chat.bus; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; import java.util.UUID; @@ -18,12 +19,16 @@ public class ChatRedisPublisher { private final String nodeId = System.getProperty("node.id", java.lang.management.ManagementFactory.getRuntimeMXBean().getName()); - public void publishToRoom(String roomId, Map payload) { - try { - payload.put("_src", nodeId); // 루프 방지 태그 + public void publishToRoom(String roomId, Map payload) throws JsonProcessingException { + System.out.println("roomId = "+roomId); + System.out.println("payload = "+payload); + + //payload.put("_src", nodeId()); // 루프 방지 태그 String json = objectMapper.writeValueAsString(payload); + System.out.println("publishToRoom = "+json); + stringRedisTemplate.convertAndSend(roomId, json); - } catch (Exception ignore) {} + } public String nodeId() { return nodeId; } diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/controller/ChatMessagingController.java b/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/controller/ChatMessagingController.java index 1aab097..e2b270c 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/controller/ChatMessagingController.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/domain/chat/controller/ChatMessagingController.java @@ -1,6 +1,7 @@ package likelion.mlb.backendProject.domain.chat.controller; +import com.fasterxml.jackson.core.JsonProcessingException; import java.security.Principal; import java.util.Map; import java.util.UUID; @@ -28,10 +29,9 @@ public class ChatMessagingController { @Transactional - @MessageMapping("/chat/{roomId}/send") - public void send(@DestinationVariable UUID roomId, - ChatSendRequest req, - Principal principal) { + @MessageMapping("/chat/send") + public void send(ChatSendRequest req, + Principal principal) throws JsonProcessingException { UUID userId = null; if (principal instanceof Authentication auth @@ -40,7 +40,7 @@ public void send(@DestinationVariable UUID roomId, } // ✅ 방 멤버인지 권한 체크 (아니면 바로 거절) - if (userId == null || !membershipRepository.isMember(roomId, userId)) { + if (userId == null || !membershipRepository.isMember(req.getRoomId(), userId)) { throw new org.springframework.messaging.MessagingException("Not a member of this chat room"); // 또는 그냥 return; // 조용히 무시하고 싶으면 } @@ -49,11 +49,11 @@ public void send(@DestinationVariable UUID roomId, System.out.println("------------/chat/{roomId}/send 시작 "); // 안전장치: 메시지의 roomId는 URL의 roomId로 강제 - ChatMessage saved = chatMessageService.saveUserMessage(roomId, userId, req.getContent()); + ChatMessage saved = chatMessageService.saveUserMessage(req.getRoomId(), userId, req.getContent()); Map payload = Map.of( "id", saved.getId().toString(), - "chatRoomId", roomId.toString(), + "chatRoomId", req.getRoomId().toString(), "type", saved.getMessageType().name(), "content", saved.getContent(), "userId", userId != null ? userId.toString() : null, @@ -66,9 +66,9 @@ public void send(@DestinationVariable UUID roomId, System.out.println("------------받은메세지"+req.getContent()); // ✅ 즉시 현재 노드의 클라이언트에게 전달 - //messagingTemplate.convertAndSend("/topic/chat/" + roomId, payload); + messagingTemplate.convertAndSend("/topic/chat/" + req.getRoomId(), payload); // ✅ 다른 노드를 위해 Redis로도 전달 - chatRedisPublisher.publishToRoom("/topic/chat/" + roomId, new java.util.HashMap<>(payload)); + chatRedisPublisher.publishToRoom("chat." + req.getRoomId(), payload); } } diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/global/configuration/RedisConfig.java b/backendProject/src/main/java/likelion/mlb/backendProject/global/configuration/RedisConfig.java index 0a958d0..77b0781 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/global/configuration/RedisConfig.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/global/configuration/RedisConfig.java @@ -62,6 +62,7 @@ public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnecti RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(new MessageListenerAdapter(redisSubscriber), new PatternTopic("draft.*")); + container.addMessageListener(new MessageListenerAdapter(redisSubscriber), new PatternTopic("chat/*")); return container; } } diff --git a/backendProject/src/main/java/likelion/mlb/backendProject/global/redis/RedisSubscriber.java b/backendProject/src/main/java/likelion/mlb/backendProject/global/redis/RedisSubscriber.java index eee4ff7..143e601 100644 --- a/backendProject/src/main/java/likelion/mlb/backendProject/global/redis/RedisSubscriber.java +++ b/backendProject/src/main/java/likelion/mlb/backendProject/global/redis/RedisSubscriber.java @@ -27,7 +27,8 @@ public void onMessage(Message message, byte[] pattern) { String msgBody = new String(message.getBody()); DraftRequest draftRequest = objectMapper.readValue(msgBody, DraftRequest.class); - simpMessagingTemplate.convertAndSend("/topic/draft." + draftRequest.getDraftId(), draftRequest); +// simpMessagingTemplate.convertAndSend("/topic/draft." + draftRequest.getDraftId(), draftRequest); + simpMessagingTemplate.convertAndSend("/chat/" + draftRequest.getDraftId(), draftRequest); } catch (Exception e) { }