From a5dd9e33fe48e76b5ff0cf695f0a2f220a138d96 Mon Sep 17 00:00:00 2001 From: imjanghyeok Date: Sun, 12 May 2024 16:09:50 +0900 Subject: [PATCH 1/4] =?UTF-8?q?Refactor:=20getMessagePage=20api=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EB=B0=8F=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=84=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=8B=A4=EC=8B=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/service/MessageService.java | 79 +++++++++++++++++-- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/src/main/java/capstone/facefriend/chat/service/MessageService.java b/src/main/java/capstone/facefriend/chat/service/MessageService.java index 84721398c6..628ac12647 100644 --- a/src/main/java/capstone/facefriend/chat/service/MessageService.java +++ b/src/main/java/capstone/facefriend/chat/service/MessageService.java @@ -7,6 +7,7 @@ import capstone.facefriend.chat.service.dto.heart.HeartReplyRequest; import capstone.facefriend.chat.service.dto.heart.HeartReplyResponse; import capstone.facefriend.chat.service.dto.heart.SendHeartResponse; +import capstone.facefriend.chat.service.dto.message.MessageListRequest; import capstone.facefriend.chat.service.dto.message.MessageListResponse; import capstone.facefriend.chat.service.dto.message.MessageRequest; import capstone.facefriend.chat.service.dto.message.MessageResponse; @@ -227,15 +228,13 @@ public void heartReply(HeartReplyRequest heartReplyRequest, Long receiveId) { simpMessagingTemplate.convertAndSend(destination, heartReplyResponse); } - public List getMessagePage(Long roomId, Long memberId, int pageNo) { + public List getMessagePage(Long roomId, int pageNo, MessageListRequest messageListRequest) { pageNo = pageNo - 1; int pageSize = 40; Sort sort = Sort.by(Sort.Direction.DESC, "sendTime"); Pageable pageable = PageRequest.of(pageNo, pageSize, sort); - String chatRoomInfoId = roomId + "/member/" + memberId; - ChatRoomInfo chatRoomInfo = findChatRoomInfo(chatRoomInfoId); - LocalDateTime time = chatRoomInfo.getEnterTime(); - List chatMessagePage = chatMessageRepository.findChatMessagesByChatRoom_IdAndSendTimeBefore(roomId, time, pageable); + LocalDateTime time2 = messageListRequest.sendTime(); + List chatMessagePage = chatMessageRepository.findChatMessagesByChatRoom_IdAndSendTimeBefore(roomId, time2, pageable); List messageListResponses = new ArrayList<>(); for (ChatMessage chatMessage : chatMessagePage){ MessageListResponse messageListResponse = MessageListResponse.of(chatMessage); @@ -243,4 +242,74 @@ public List getMessagePage(Long roomId, Long memberId, int } return messageListResponses; } + + @Transactional + public void enterApplication(Long memberId) { + String exceptionDestination = "/sub/chat/" + memberId; + SocketInfo socketInfo = new SocketInfo(); + socketInfo.setMemberId(memberId); + socketInfo.setConnectTime(LocalDateTime.now()); + socketInfoRedisRepository.save(socketInfo); + if (isExistUnReadMessage(memberId)) { + sendSentMessage(memberId); + } + + if(isExistUnSendHeart(memberId)) { + sendSentHeart(memberId); + } + + simpMessagingTemplate.convertAndSend(exceptionDestination, "저장 성공"); + } + + @Transactional + public String exitApplication(Long memberId) { + SocketInfo socketInfo = findSocketInfo(memberId); + socketInfoRedisRepository.delete(socketInfo); + return "성공"; + } + + private Boolean isExistUnReadMessage(Long memberId) { + Boolean isUnRead = redisTemplate.hasKey("/sub/chat/" + memberId + "message"); + log.info(isUnRead.toString()); + return !isUnRead; + } + + private Boolean isExistUnSendHeart(Long memberId) { + Boolean isUnRead = redisTemplate.hasKey("/sub/chat/" + memberId + "SendHeart"); + log.info(isUnRead.toString()); + return !isUnRead; + } + + private void sendSentMessage(Long receiveId) { + String topic = channelTopic.getTopic(); + String destination = "/sub/chat" + receiveId + "message"; + Long messagesListSize = redisTemplate.opsForList().size(destination); + log.info(messagesListSize.toString()); + log.info("messageList: {}", redisTemplate.opsForList().range(destination, 0, -1)); + + if (messagesListSize > 0) { + for (Long i = messagesListSize; i > 0; i--) { + // 맵으로 받음 + LinkedHashMap map = (LinkedHashMap) redisTemplate.opsForList().rightPop(destination); + MessageResponse messageResponse = (MessageResponse) map.get(destination); + log.info("messageResponse: {}", messageResponse.toString()); + redisTemplate.convertAndSend(topic, messageResponse); + } + } + } + + private void sendSentHeart(Long receiveId) { + String topic = channelTopic.getTopic(); + String destination = "/sub/chat" + receiveId + "heart"; + Long messagesListSize = redisTemplate.opsForList().size(destination); + log.info("SendHeartListSize: {}", messagesListSize.toString()); + if (messagesListSize > 0) { + for (Long i = messagesListSize; i > 0; i--) { + LinkedHashMap map = (LinkedHashMap) redisTemplate.opsForList().rightPop(destination); + SendHeartResponse sendHeartResponse = (SendHeartResponse) map.get(destination); + log.info("messageResponse: {}", sendHeartResponse.toString()); + redisTemplate.convertAndSend(topic, sendHeartResponse); + } + } + } } \ No newline at end of file From 1d63f962650b922e7b8b99019e1b7ecde8d6be91 Mon Sep 17 00:00:00 2001 From: imjanghyeok Date: Sun, 12 May 2024 16:10:25 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Refactor:=20=EC=9D=B4=EC=A0=84=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EB=8B=A4=EC=8B=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20RedisSubscriber=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=84=20=EB=B2=84=EC=A0=84=EC=9C=BC=EB=A1=9C=20=EB=B3=B5?= =?UTF-8?q?=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/service/RedisSubscriber.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/main/java/capstone/facefriend/chat/service/RedisSubscriber.java b/src/main/java/capstone/facefriend/chat/service/RedisSubscriber.java index 22db6c6d0b..8d96edf7a7 100644 --- a/src/main/java/capstone/facefriend/chat/service/RedisSubscriber.java +++ b/src/main/java/capstone/facefriend/chat/service/RedisSubscriber.java @@ -33,18 +33,64 @@ public void onMessage(Message message, byte[] pattern) { try { // redis에서 발행된 데이터를 받아 역직렬화 String publishMessage = (String) redisTemplate.getStringSerializer().deserialize(message.getBody()); - if (publishMessage.contains("message")) { + log.info(publishMessage); MessageResponse messageResponse = objectMapper.readValue(publishMessage, MessageResponse.class); + log.info(messageResponse.toString()); GetMessageResponse chatMessageResponse = new GetMessageResponse(messageResponse); + log.info(chatMessageResponse.toString()); + if (isExistSubscriber(messageResponse.getReceiveId())) { + messagingTemplate.convertAndSend("/sub/chat/" + messageResponse.getReceiveId(), chatMessageResponse); + } else { + saveUnReadMessage("/sub/chat" + messageResponse.getReceiveId() + "message", messageResponse); + } + + messagingTemplate.convertAndSend("/sub/chat/" + messageResponse.getReceiveId(), chatMessageResponse); } else if (publishMessage.contains("Heart")) { SendHeartResponse sendHeartResponse = objectMapper.readValue(publishMessage, SendHeartResponse.class); + GetSendHeartResponse chatSendHeartResponse = new GetSendHeartResponse(sendHeartResponse); + if (isExistSubscriber(chatSendHeartResponse.getReceiveId())) { + messagingTemplate.convertAndSend("/sub/chat/" + sendHeartResponse.getReceiveId(), chatSendHeartResponse); + } else { + saveUnReadHeart("/sub/chat" + sendHeartResponse.getReceiveId() + "heart", sendHeartResponse); + } + messagingTemplate.convertAndSend("/sub/chat/" + sendHeartResponse.getReceiveId(), chatSendHeartResponse); } } catch (IOException e) { throw new RuntimeException("Failed to process message", e); } } + + private Boolean isExistSubscriber(Long memberId) { + log.info("isExistSubscriber 호출"); + Boolean isMember = redisTemplate.opsForSet().isMember("SocketInfo", memberId); + log.info("Socket: " + memberId); + log.info("SocketInfo: " + isMember); + + return isMember; + } + + + + private void saveUnReadMessage(String destination, MessageResponse messageResponse) { + Boolean isUnRead = redisTemplate.hasKey(destination); + log.info(isUnRead.toString()); + if (isUnRead) { + redisTemplate.opsForList().rightPush(destination, messageResponse); + } else { + redisTemplate.opsForList().rightPush(destination, messageResponse); + } + } + + private void saveUnReadHeart(String destination, SendHeartResponse sendHeartResponse) { + Boolean isUnRead = redisTemplate.hasKey(destination); + if (isUnRead) { + redisTemplate.opsForList().rightPush(destination, sendHeartResponse); + } else { + redisTemplate.opsForList().rightPush(destination, sendHeartResponse); + } + } } \ No newline at end of file From a75efc86ae7bca78536c11499f1be8318de55461 Mon Sep 17 00:00:00 2001 From: imjanghyeok Date: Sun, 12 May 2024 16:10:53 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Refactor:=20getMessagePage=20api=20request?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/service/dto/message/MessageListRequest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/capstone/facefriend/chat/service/dto/message/MessageListRequest.java diff --git a/src/main/java/capstone/facefriend/chat/service/dto/message/MessageListRequest.java b/src/main/java/capstone/facefriend/chat/service/dto/message/MessageListRequest.java new file mode 100644 index 0000000000..c8c19b6791 --- /dev/null +++ b/src/main/java/capstone/facefriend/chat/service/dto/message/MessageListRequest.java @@ -0,0 +1,11 @@ +package capstone.facefriend.chat.service.dto.message; + +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +public record MessageListRequest( + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm") + LocalDateTime sendTime +) { +} From fb2f8ed4d8c98144a491080ffa2f43e8d8a61a66 Mon Sep 17 00:00:00 2001 From: imjanghyeok Date: Sun, 12 May 2024 16:10:58 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Refactor:=20getMessagePage=20api=20request?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/controller/MessageController.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/capstone/facefriend/chat/controller/MessageController.java b/src/main/java/capstone/facefriend/chat/controller/MessageController.java index 5ce6840308..bba738abda 100644 --- a/src/main/java/capstone/facefriend/chat/controller/MessageController.java +++ b/src/main/java/capstone/facefriend/chat/controller/MessageController.java @@ -5,6 +5,7 @@ import capstone.facefriend.chat.service.MessageService; import capstone.facefriend.chat.service.dto.heart.HeartReplyRequest; import capstone.facefriend.chat.service.dto.heart.SendHeartRequest; +import capstone.facefriend.chat.service.dto.message.MessageListRequest; import capstone.facefriend.chat.service.dto.message.MessageListResponse; import capstone.facefriend.chat.service.dto.message.MessageRequest; import lombok.RequiredArgsConstructor; @@ -25,13 +26,32 @@ public class MessageController { private final MessageService messageService; private final JwtProvider jwtProvider; + @MessageMapping("/stomp/connect") + public void enterApp( + StompHeaderAccessor headerAccessor + ){ + String authorizationHeader = headerAccessor.getFirstNativeHeader("Authorization"); + String token = authorizationHeader.substring(BEARER_PREFIX.length()); + Long memberId = jwtProvider.extractId(token); + messageService.enterApplication(memberId); + } + + @PostMapping("/stomp/disconnect") + public String exitApp( + @AuthMember Long memberId + ){ + String msg = messageService.exitApplication(memberId); + return msg; + } + @GetMapping("/chat/{roomId}/messages") public ResponseEntity> getMessagesPage( @PathVariable("roomId") Long roomId, - @AuthMember Long memberId, - @RequestParam(required = false, defaultValue = "1", value = "page") int pageNo +// @AuthMember Long memberId, + @RequestParam(required = false, defaultValue = "1", value = "page") int pageNo, + @RequestBody MessageListRequest messageListRequest ){ - return ResponseEntity.ok(messageService.getMessagePage(roomId, memberId,pageNo)); + return ResponseEntity.ok(messageService.getMessagePage(roomId, pageNo, messageListRequest)); }