-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[refactor] 채팅 중복 체크 로직 추가 및 채팅방 멤버 리스트 관리 로직 추가 #287
Closed
Closed
Changes from 8 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
c956760
[refactor] 중복 입장 로직, 채팅방 멤버 리스트 관리 로직 추가
mooncw e609e2e
[test] 중복 입장 로직, 채팅방 멤버 리스트 관리 로직 추가에 따른 테스트 코드 수정
mooncw 2f3345d
[chore] 충돌 해결
mooncw e73ba04
[refactor] 채팅방 인원 제한 로직 추가
mooncw e0b1168
[refactor] 채팅방 내역 조회 속성에 senderId와 senderImageUrl 추가
mooncw 88a6743
[chore] 리뷰 반영 1차
mooncw f2041fb
[fix] 에러 메시지인데, 커스텀 성공 코드로 응답하는 것으로 잘못 구현해서 수정
mooncw c00225c
[fix] 존재하지 않는 NativeHeader를 유효하지 않는 NativeHeader로 수정
mooncw 8dd7f0a
fix: 모각코 PR 충돌 해결
mooncw f8c6103
fix: #321 #323 PR 충돌 해결
mooncw 23865db
fix: 리뷰 1차 반영
mooncw 553c543
fix: 입장 퇴장 관련 로직 보완
mooncw e825f51
test: 바뀐 채팅방 입장하기 api 응답에 따른 테스트 코드 수정
mooncw 14a0ec0
fix: 프론트와 맞추면서 로직 수정
mooncw c1f6e2f
chore: #332 PR 충돌 해결
mooncw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
...in/java/com/kernelsquare/memberapi/domain/coffeechat/component/ChatRoomMemberManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.kernelsquare.memberapi.domain.coffeechat.component; | ||
|
||
import com.kernelsquare.core.common_response.error.code.MemberErrorCode; | ||
import com.kernelsquare.core.common_response.error.exception.BusinessException; | ||
import com.kernelsquare.domainmysql.domain.member.entity.Member; | ||
import com.kernelsquare.domainmysql.domain.member.repository.MemberRepository; | ||
import com.kernelsquare.memberapi.domain.coffeechat.dto.ChatRoomMember; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
public class ChatRoomMemberManager { | ||
private final MemberRepository memberRepository; | ||
private final ConcurrentHashMap<String, List<ChatRoomMember>> chatRoomMap = new ConcurrentHashMap<>(); | ||
|
||
public void addChatRoom(String roomKey) { | ||
chatRoomMap.computeIfAbsent(roomKey, k -> new ArrayList<>()); | ||
} | ||
|
||
public void addChatMember(String roomKey, Long memberId) { | ||
Member member = memberRepository.findById(memberId) | ||
.orElseThrow(() -> new BusinessException(MemberErrorCode.MEMBER_NOT_FOUND)); | ||
|
||
chatRoomMap.computeIfAbsent(roomKey, k -> new ArrayList<>()).add(ChatRoomMember.from(member)); | ||
} | ||
|
||
public List<ChatRoomMember> getChatRoom(String roomKey) { | ||
return chatRoomMap.getOrDefault(roomKey, new ArrayList<>()); | ||
} | ||
|
||
public void removeChatRoomMember(String roomKey, Long memberId) { | ||
List<ChatRoomMember> chatRoomMemberList = getChatRoom(roomKey); | ||
|
||
ChatRoomMember member = chatRoomMemberList.stream() | ||
.filter(chatRoomMember -> chatRoomMember.memberId().equals(memberId)) | ||
.findFirst() | ||
.orElseThrow(() -> new BusinessException(MemberErrorCode.MEMBER_NOT_FOUND)); | ||
|
||
chatRoomMemberList.remove(member); | ||
} | ||
|
||
public Integer countChatRoomMember(String roomKey) { | ||
List<ChatRoomMember> chatRoomMemberList = getChatRoom(roomKey); | ||
|
||
return chatRoomMemberList.size(); | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
...pi/src/main/java/com/kernelsquare/memberapi/domain/coffeechat/component/StompHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.kernelsquare.memberapi.domain.coffeechat.component; | ||
|
||
import com.kernelsquare.core.common_response.error.code.CoffeeChatErrorCode; | ||
import com.kernelsquare.core.common_response.error.exception.BusinessException; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.messaging.Message; | ||
import org.springframework.messaging.MessageChannel; | ||
import org.springframework.messaging.simp.stomp.StompCommand; | ||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor; | ||
import org.springframework.messaging.support.ChannelInterceptor; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Objects; | ||
|
||
/* 메시지가 보내진 후 해당 메시지를 인터셉트하여 핸들링하기 위한 클래스 */ | ||
@Slf4j | ||
@Component | ||
@RequiredArgsConstructor | ||
public class StompHandler implements ChannelInterceptor { | ||
private final ChatRoomMemberManager chatRoomMemberManager; | ||
@Override | ||
public void postSend(Message message, MessageChannel channel, boolean sent) { | ||
StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message); | ||
StompCommand command = accessor.getCommand(); | ||
|
||
if (Objects.isNull(command)) { | ||
throw new BusinessException(CoffeeChatErrorCode.MESSAGE_COMMAND_NOT_VALID); | ||
} | ||
|
||
switch (command) { | ||
case SUBSCRIBE -> handleSubscribeEvent(message); | ||
case DISCONNECT -> handleDisconnectEvent(message); | ||
default -> {} | ||
} | ||
} | ||
|
||
private void handleSubscribeEvent(Message message) { | ||
StompMessageParser parser = new StompMessageParser(message); | ||
|
||
String roomKey = parser.getRoomKey(); | ||
Long memberId = parser.getMemberId(); | ||
|
||
chatRoomMemberManager.addChatMember(roomKey, memberId); | ||
} | ||
|
||
private void handleDisconnectEvent(Message message) { | ||
StompMessageParser parser = new StompMessageParser(message); | ||
|
||
String roomKey = parser.getRoomKey(); | ||
Long memberId = parser.getMemberId(); | ||
|
||
chatRoomMemberManager.removeChatRoomMember(roomKey, memberId); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
.../main/java/com/kernelsquare/memberapi/domain/coffeechat/component/StompMessageParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.kernelsquare.memberapi.domain.coffeechat.component; | ||
|
||
import com.kernelsquare.core.common_response.error.code.CoffeeChatErrorCode; | ||
import com.kernelsquare.core.common_response.error.exception.BusinessException; | ||
import org.springframework.messaging.Message; | ||
import org.springframework.messaging.simp.stomp.StompCommand; | ||
import org.springframework.messaging.simp.stomp.StompHeaderAccessor; | ||
|
||
import java.util.Arrays; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
|
||
/* STOMP 메시지 헤더에서 필요한 데이터를 가져오기 위한 클래스 */ | ||
public class StompMessageParser { | ||
private final StompHeaderAccessor accessor; | ||
|
||
public StompMessageParser(Message message) { | ||
this.accessor = StompHeaderAccessor.wrap(message); | ||
} | ||
|
||
public String getRoomKey() { | ||
if (Objects.equals(accessor.getCommand(), StompCommand.SUBSCRIBE)) { | ||
String destination = Optional.ofNullable(accessor.getDestination()) | ||
.orElseThrow(() -> new BusinessException(CoffeeChatErrorCode.MESSAGE_DESTINATION_NOT_VALID)); | ||
|
||
return Arrays.stream(destination.split("/")) | ||
.reduce((first, second) -> second) | ||
.get(); | ||
} | ||
|
||
String roomKey = Optional.ofNullable(accessor.getNativeHeader("roomKey").getFirst()) | ||
.orElseThrow(() -> new BusinessException(CoffeeChatErrorCode.MESSAGE_NATIVEHEADER_NOT_FOUND)); | ||
|
||
return roomKey; | ||
} | ||
|
||
public Long getMemberId() { | ||
Long memberId = Optional.ofNullable(Long.valueOf(accessor.getNativeHeader("memberId").getFirst())) | ||
.orElseThrow(() -> new BusinessException(CoffeeChatErrorCode.MESSAGE_NATIVEHEADER_NOT_FOUND)); | ||
|
||
return memberId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 0 additions & 20 deletions
20
...in/java/com/kernelsquare/memberapi/domain/coffeechat/dto/CreateCoffeeChatRoomRequest.java
This file was deleted.
Oops, something went wrong.
13 changes: 0 additions & 13 deletions
13
...n/java/com/kernelsquare/memberapi/domain/coffeechat/dto/CreateCoffeeChatRoomResponse.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동시에 입장해서 멤버목록을 관리한다고 하면 List 보다 Collections.synchronizedList 를 고려해봐도 좋을 것 같습니다.
물론 지금은 2명 입장이라 괜찮을 것 같지만 그룹으로 확대된다고 했을 때를 생각해보면 한번 고민해봐도 좋을 것 같네요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
멤버 목록은 ConcurrentHashMap 안에 있기 때문에 List여도 상관없다고 생각했는데, 다른 분들의 생각은 어떠신가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List 대신 CopyOnWriteArraySet를 사용했습니다.