Skip to content

Commit

Permalink
feat: 방을 나가면 전체 WAS 서버에서 기존 연결을 끊을 수 있도록 기능추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Curry4182 committed Apr 12, 2024
1 parent 3300a01 commit 4fc555b
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.springframework.stereotype.Service;

Expand All @@ -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;

Expand All @@ -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();
Expand All @@ -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<String> 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);
}
}
Original file line number Diff line number Diff line change
@@ -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<String> 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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
Original file line number Diff line number Diff line change
@@ -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<String, Object> 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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.programmers.lime.redis.chat.model;

import lombok.Builder;

@Builder
public record ChatRoomRemoveAllSessionInfo(
Long roomId,
Long memberId
) {
}
Original file line number Diff line number Diff line change
@@ -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<String, Object> redisTemplate;

public void removeAllSession(final String channel,
final ChatRoomRemoveAllSessionInfo chatRoomRemoveAllSessionInfo) {
redisTemplate.convertAndSend(channel, chatRoomRemoveAllSessionInfo);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 4fc555b

Please sign in to comment.