처음에는 단순히 채팅방의 인원 수 속성만 추가하여 사용자가 채팅방에 입장하고 퇴장할 때마다 인원 수를 증가시키거나 감소시켜주었다.
하지만 채팅방을 나가지 않고 그냥 다른 페이지에 갔다가 다시 채팅방에 들어와도 중복으로 숫자가 증가했다. 즉 같은 사람이 계속 채팅방에 들어오면 그대로 숫자가 증가해서 이런 방법으로는 구현을 할 수 없다고 생각했다.
나는 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 에서 없애주었다