[내일배움캠프] #211215 💻 TIL 💻

이수영·2021년 12월 15일
1

MY TIL 

목록 보기
49/50
post-thumbnail

📚 Springboot

✍🏻 채팅방 인원 수 구현

🚫 Problem

처음에는 단순히 채팅방의 인원 수 속성만 추가하여 사용자가 채팅방에 입장하고 퇴장할 때마다 인원 수를 증가시키거나 감소시켜주었다.

하지만 채팅방을 나가지 않고 그냥 다른 페이지에 갔다가 다시 채팅방에 들어와도 중복으로 숫자가 증가했다. 즉 같은 사람이 계속 채팅방에 들어오면 그대로 숫자가 증가해서 이런 방법으로는 구현을 할 수 없다고 생각했다.

✔ Solution

나는 ChatUser 라는 entity를 만들어서 인원수를 구해야한다는 해결방법을 얻었다.

  • ChatUser 라는 entity를 만들어서 속성을 채팅방 , 사용자로 정의한다
  • ChatUser는 채팅방에 들어간 사람을 뜻하는 entity 로 사용자가 채팅방에 입장하였을 때 생성된다
  • 이 생성은 이 사용자가 이미 채팅방에 존재하는 지 판단하는 과정을 거치고 생성하기 때문에 이 사용자가 채팅방을 나가지 않았을 경우에는 다시 생성되지 않고 재입장메시지가 사용자에게 보내진다.
@Slf4j
@Controller
@RequiredArgsConstructor
public class StompChatController {

    private final SimpMessagingTemplate template; //특정 Broker로 메세지를 전달
    private final ChatRoomRepository chatRoomRepository;
    private final ChatUserRepository chatUserRepository;
    private final UserRepository userRepository;

    //stompConfig에서 설정한 applicationDestinationPrefixes와 @MessageMapping 경로가 병합됨
    //"/pub/chat/enter"
    @MessageMapping(value = "/chat/enter")
    public void enter(ChatMessageDTO message) {
        String id = message.getRoomId();
        Long room_id = Long.valueOf(id);

        // chat user 정보 저장 (채팅유저 , 채팅방)
        ChatRoom chatRoom = chatRoomRepository.findByRoomId(room_id).orElseThrow(
                () -> new NullPointerException("해당 채팅방이 존재하지 않습니다."));
        User user = userRepository.findByUsername(message.getWriter()).orElseThrow(
                () -> new NullPointerException("해당 사용자가 존재하지 않습니다."));


        if (!(chatUserRepository.findByChatRoomAndUser(chatRoom, user).isPresent())) { //채팅방 처음입장
            ChatUser chatUser = new ChatUser(user, chatRoom);
            chatUserRepository.save(chatUser);
            int count  =chatUserRepository.countByChatRoom(chatRoom);

            chatRoom.setCount(count);
            chatRoomRepository.save(chatRoom);

            message.setMessage("채팅방에 참여하였습니다.");
            template.convertAndSend("/sub/chat/room/" + message.getRoomId(), message);
        }
        else
        {
            message.setMessage("채팅방에 재입장하였습니다.");
            template.convertAndSend("/sub/chat/room/" + message.getRoomId(), message);
        }
    }

    @Transactional
    @MessageMapping(value = "/chat/exit")
    public void exit(ChatMessageDTO message) {
        String id=message.getRoomId();
        Long room_id = Long.valueOf(id);

        // chat user 정보 삭제 (채팅유저 , 채팅방)
        ChatRoom chatRoom = chatRoomRepository.findById(room_id).orElseThrow(
                ()->new NullPointerException("해당 채팅방이 존재하지 않습니다."));
        User user= userRepository.findByUsername(message.getWriter()).orElseThrow(
                ()->new NullPointerException("해당 사용자가 존재하지 않습니다."));


        chatUserRepository.deleteByChatRoomAndUser(chatRoom,user);
        int count  =chatUserRepository.countByChatRoom(chatRoom);
        chatRoom.setCount(count);
        chatRoomRepository.save(chatRoom);

        message.setMessage("채팅방을 나갔습니다.");
        template.convertAndSend("/sub/chat/room/" + message.getRoomId(), message);
    }

    @MessageMapping(value = "/chat/message")
    public void message(ChatMessageDTO message){
        template.convertAndSend("/sub/chat/room/" + message.getRoomId(), message);
    }
}
  • 채팅방 들어오기 : ChatUser를 존재유무에 따라 생성한 후 ChatUserRepository에서 Chatroom 에 해당하는 user 가 몇 명 있는지 구한 후 Chatroom count에 update 해주고 다시 레포지토리에 넣어준다

  • 채팅방 나가기 : 채팅방 들어오기와 비슷하다 . 하지만 채팅방에서 나가는 것은 들어왓다는 가정하에 이루어지기 때문에 존재 유무 확인 과정은 뺐다. ChatRoom 고 User 정보를 찾아서 ChatUser 에서 없애주었다

To do

  • 이미 채팅방에 들어와있던 사용자가 다른페이지에 갔다가 다시 들어올 경우 메시지가 그대로 남아있는것
    => 해결방법 1. 사용자의 로컬스토리지에 저장 => 브라우저 닫으면 지워지도록
    => 해결방법 2. 서버에 저장 => 부하가 일어날 가능성 크지만 현업에서는 보통 이러한 방식을 사용한다.
profile
Hongik Univ 💻

0개의 댓글