From 4fc555b3593fff3b185e9b95af892beaf29d1557 Mon Sep 17 00:00:00 2001 From: Curry4182 Date: Fri, 12 Apr 2024 11:05:08 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B0=A9=EC=9D=84=20=EB=82=98=EA=B0=80?= =?UTF-8?q?=EB=A9=B4=20=EC=A0=84=EC=B2=B4=20WAS=20=EC=84=9C=EB=B2=84?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B8=B0=EC=A1=B4=20=EC=97=B0=EA=B2=B0?= =?UTF-8?q?=EC=9D=84=20=EB=81=8A=EC=9D=84=20=EC=88=98=20=EC=9E=88=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatroom/application/ChatRoomService.java | 29 +++++--------- .../ChatRoomRemoveSessionListener.java | 40 +++++++++++++++++++ .../chat/ChatRedisMessageBrokerConfig.java | 35 +++++++++++----- .../ChatRoomRemoveAllSessionListenerImpl.java | 35 ++++++++++++++++ .../IChatRoomRemoveSessionListener.java | 8 ++++ .../model/ChatRoomRemoveAllSessionInfo.java | 10 +++++ .../ChatRoomRemoveSessionPublisher.java | 20 ++++++++++ .../IChatRoomRemoveSessionPublisher.java | 7 ++++ 8 files changed, 153 insertions(+), 31 deletions(-) create mode 100644 lime-api/src/main/java/com/programmers/lime/global/config/chat/message/ChatRoomRemoveSessionListener.java create mode 100644 lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/ChatRoomRemoveAllSessionListenerImpl.java create mode 100644 lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/IChatRoomRemoveSessionListener.java create mode 100644 lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/model/ChatRoomRemoveAllSessionInfo.java create mode 100644 lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/ChatRoomRemoveSessionPublisher.java create mode 100644 lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/IChatRoomRemoveSessionPublisher.java diff --git a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java index 68aabf24..3319badc 100644 --- a/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java +++ b/lime-api/src/main/java/com/programmers/lime/domains/chatroom/application/ChatRoomService.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.Objects; -import java.util.Set; import org.springframework.stereotype.Service; @@ -14,9 +13,9 @@ import com.programmers.lime.domains.chatroom.model.ChatRoomInfo; import com.programmers.lime.error.BusinessException; import com.programmers.lime.error.ErrorCode; -import com.programmers.lime.global.config.chat.WebSocketSessionManager; import com.programmers.lime.global.config.security.SecurityUtils; -import com.programmers.lime.redis.chat.ChatSessionRedisManager; +import com.programmers.lime.redis.chat.model.ChatRoomRemoveAllSessionInfo; +import com.programmers.lime.redis.chat.publisher.IChatRoomRemoveSessionPublisher; import lombok.RequiredArgsConstructor; @@ -32,9 +31,7 @@ public class ChatRoomService { private final ChatRoomReader chatRoomReader; - private final WebSocketSessionManager webSocketSessionManager; - - private final ChatSessionRedisManager chatSessionRedisManager; + private final IChatRoomRemoveSessionPublisher removeSessionPublisher; public ChatRoomGetServiceListResponse getAvailableChatRooms() { Long memberId = SecurityUtils.getCurrentMemberId(); @@ -60,26 +57,18 @@ public void joinChatRoom(final Long chatRoomId) { chatRoomMemberAppender.appendChatRoomMember(chatRoomId, memberId); } - public int countChatRoomMembersByChatRoomId(Long chatRoomId) { + public int countChatRoomMembersByChatRoomId(final Long chatRoomId) { return chatRoomMemberReader.countChatRoomMembersByChatRoomId(chatRoomId); } public void exitChatRoom(final Long chatRoomId) { Long memberId = SecurityUtils.getCurrentMemberId(); + ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo = ChatRoomRemoveAllSessionInfo.builder() + .memberId(memberId) + .roomId(chatRoomId) + .build(); - Set sessionIdsByMemberAndRoom = chatSessionRedisManager.getSessionIdsByMemberAndRoom( - memberId, - chatRoomId - ); - - for(String memberSessionId : sessionIdsByMemberAndRoom) { - try { - webSocketSessionManager.closeSession(memberSessionId); - } catch (Exception e) { - throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND); - } - } - + removeSessionPublisher.removeAllSession("sub-chatroom-remove-session", chatRoomRemoveAllSessionInfo); chatRoomMemberRemover.removeChatRoomMember(chatRoomId, memberId); } } diff --git a/lime-api/src/main/java/com/programmers/lime/global/config/chat/message/ChatRoomRemoveSessionListener.java b/lime-api/src/main/java/com/programmers/lime/global/config/chat/message/ChatRoomRemoveSessionListener.java new file mode 100644 index 00000000..23841a27 --- /dev/null +++ b/lime-api/src/main/java/com/programmers/lime/global/config/chat/message/ChatRoomRemoveSessionListener.java @@ -0,0 +1,40 @@ +package com.programmers.lime.global.config.chat.message; + +import java.util.Set; + +import org.springframework.stereotype.Component; + +import com.programmers.lime.error.BusinessException; +import com.programmers.lime.error.ErrorCode; +import com.programmers.lime.global.config.chat.WebSocketSessionManager; +import com.programmers.lime.redis.chat.ChatSessionRedisManager; +import com.programmers.lime.redis.chat.listener.IChatRoomRemoveSessionListener; +import com.programmers.lime.redis.chat.model.ChatRoomRemoveAllSessionInfo; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ChatRoomRemoveSessionListener implements IChatRoomRemoveSessionListener { + + private final ChatSessionRedisManager chatSessionRedisManager; + + private final WebSocketSessionManager webSocketSessionManager; + + @Override + public void removeAllSession(final ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo) { + + Set sessionIdsByMemberAndRoom = chatSessionRedisManager.getSessionIdsByMemberAndRoom( + chatRoomRemoveAllSessionInfo.memberId(), + chatRoomRemoveAllSessionInfo.roomId() + ); + + for (String memberSessionId : sessionIdsByMemberAndRoom) { + try { + webSocketSessionManager.closeSession(memberSessionId); + } catch (Exception e) { + throw new BusinessException(ErrorCode.CHAT_SESSION_NOT_FOUND); + } + } + } +} diff --git a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/ChatRedisMessageBrokerConfig.java b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/ChatRedisMessageBrokerConfig.java index f529bd0b..5873419d 100644 --- a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/ChatRedisMessageBrokerConfig.java +++ b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/ChatRedisMessageBrokerConfig.java @@ -8,29 +8,42 @@ import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import com.programmers.lime.redis.chat.listener.ChatMessageListenerImpl; +import com.programmers.lime.redis.chat.listener.ChatRoomRemoveAllSessionListenerImpl; + +import lombok.RequiredArgsConstructor; @Configuration +@RequiredArgsConstructor public class ChatRedisMessageBrokerConfig { + private final ChatMessageListenerImpl chatMessageListener; + private final ChatRoomRemoveAllSessionListenerImpl chatRoomRemoveAllSessionListener; + private final RedisConnectionFactory connectionFactory; + @Bean - public RedisMessageListenerContainer redisMessageListenerContainer( - final RedisConnectionFactory connectionFactory, - final MessageListenerAdapter listenerAdapter, - final ChannelTopic channelTopic - ) { + public RedisMessageListenerContainer redisMessageListenerContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); - container.addMessageListener(listenerAdapter, channelTopic); + container.addMessageListener(addMessageListener(), chatChannelTopic()); + + container.setConnectionFactory(connectionFactory); + container.addMessageListener(removeSessionListenerAdapter(), removeSessionChannelTopic()); return container; } - @Bean - public MessageListenerAdapter listenerAdapter(final ChatMessageListenerImpl listener) { - return new MessageListenerAdapter(listener, "onMessage"); + public MessageListenerAdapter addMessageListener() { + return new MessageListenerAdapter(chatMessageListener, "onMessage"); } - @Bean - public ChannelTopic channelTopic() { + public ChannelTopic chatChannelTopic() { return new ChannelTopic("sub-chat"); } + + public MessageListenerAdapter removeSessionListenerAdapter() { + return new MessageListenerAdapter(chatRoomRemoveAllSessionListener, "onMessage"); + } + + public ChannelTopic removeSessionChannelTopic() { + return new ChannelTopic("sub-chatroom-remove-session"); + } } diff --git a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/ChatRoomRemoveAllSessionListenerImpl.java b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/ChatRoomRemoveAllSessionListenerImpl.java new file mode 100644 index 00000000..1e7054e7 --- /dev/null +++ b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/ChatRoomRemoveAllSessionListenerImpl.java @@ -0,0 +1,35 @@ +package com.programmers.lime.redis.chat.listener; + +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import com.programmers.lime.redis.chat.model.ChatRoomRemoveAllSessionInfo; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ChatRoomRemoveAllSessionListenerImpl implements MessageListener { + + private final RedisTemplate redisTemplate; + + private final IChatRoomRemoveSessionListener chatRoomRemoveSessionListener; + + @Override + public void onMessage(final Message message, final byte[] pattern) { + try { + ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo = (ChatRoomRemoveAllSessionInfo)redisTemplate.getValueSerializer() + .deserialize(message.getBody()); + + if (chatRoomRemoveAllSessionInfo == null) { + throw new IllegalStateException("Deserialized message is null. Message deserialization failed."); + } + + chatRoomRemoveSessionListener.removeAllSession(chatRoomRemoveAllSessionInfo); + } catch (Exception e) { + throw new RuntimeException("Failed to process redis message", e); + } + } +} diff --git a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/IChatRoomRemoveSessionListener.java b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/IChatRoomRemoveSessionListener.java new file mode 100644 index 00000000..53d82ef2 --- /dev/null +++ b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/listener/IChatRoomRemoveSessionListener.java @@ -0,0 +1,8 @@ +package com.programmers.lime.redis.chat.listener; + +import com.programmers.lime.redis.chat.model.ChatRoomRemoveAllSessionInfo; + +public interface IChatRoomRemoveSessionListener { + + void removeAllSession(final ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo); +} diff --git a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/model/ChatRoomRemoveAllSessionInfo.java b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/model/ChatRoomRemoveAllSessionInfo.java new file mode 100644 index 00000000..a5c721f6 --- /dev/null +++ b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/model/ChatRoomRemoveAllSessionInfo.java @@ -0,0 +1,10 @@ +package com.programmers.lime.redis.chat.model; + +import lombok.Builder; + +@Builder +public record ChatRoomRemoveAllSessionInfo( + Long roomId, + Long memberId +) { +} diff --git a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/ChatRoomRemoveSessionPublisher.java b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/ChatRoomRemoveSessionPublisher.java new file mode 100644 index 00000000..457eb091 --- /dev/null +++ b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/ChatRoomRemoveSessionPublisher.java @@ -0,0 +1,20 @@ +package com.programmers.lime.redis.chat.publisher; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; + +import com.programmers.lime.redis.chat.model.ChatRoomRemoveAllSessionInfo; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ChatRoomRemoveSessionPublisher implements IChatRoomRemoveSessionPublisher { + + private final RedisTemplate redisTemplate; + + public void removeAllSession(final String channel, + final ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo) { + redisTemplate.convertAndSend(channel, chatRoomRemoveAllSessionInfo); + } +} diff --git a/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/IChatRoomRemoveSessionPublisher.java b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/IChatRoomRemoveSessionPublisher.java new file mode 100644 index 00000000..fc7e0dd9 --- /dev/null +++ b/lime-infrastructure/src/main/java/com/programmers/lime/redis/chat/publisher/IChatRoomRemoveSessionPublisher.java @@ -0,0 +1,7 @@ +package com.programmers.lime.redis.chat.publisher; + +import com.programmers.lime.redis.chat.model.ChatRoomRemoveAllSessionInfo; + +public interface IChatRoomRemoveSessionPublisher { + void removeAllSession(String channel, ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo); +}