Dev_Henry

[Spring] 소켓통신 이용한 채팅 구현하기 4 - 채팅방 DB저장 본문

Web/Spring

[Spring] 소켓통신 이용한 채팅 구현하기 4 - 채팅방 DB저장

데브헨리 2023. 7. 21. 16:03
728x90

 

현재 프로젝트에서 구현하고자 하는 요구사항은 카카오톡처럼 클라이언트가 꺼져있을때 온 메시지도 받아야하고 내용을 유지시켜야하기 때문에 DB를 연결해야한다.

채팅내용은 어떤식으로 다룰지 고민이 필요하기 때문에 우선 채팅목록과 참여자 등을 관리할 수 있도록 먼저 구현한다.

 

 

  • chatRoomDTO
@Getter
@Setter
@NoArgsConstructor
public class ChatRoomDTO {
    private String roomId; // 채팅방 아이디
    private String roomName; // 채팅방 이름
    private long userCount; // 채팅방 인원수
    private List<String> userList = new ArrayList<>();

    public ChatRoomDTO(ChatRoom chatRoom){
        this.roomId = chatRoom.getRoomId();
        this.roomName = chatRoom.getRoomName();
        this.userCount = chatRoom.getUserCount();
        this.userList = chatRoom.getUserList().stream().map(userList-> userList.getMemberId()).collect(Collectors.toList());
    }
}
 
  • chatRoom
@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRoom {
    @Id
    private String roomId; // 채팅방 아이디
    private String roomName; // 채팅방 이름
    private long userCount; // 채팅방 인원수
    @OneToMany
    @Builder.Default
    private List<Member> userList = new ArrayList<>();

    public void upUserCount(){
        this.userCount++;
    }
    public void downUserCount(){
        this.userCount--;
    }
    public void addUser(Member userName){
        this.userList.add(userName);
    }
    public void removeUser(Member userName){
        this.userList.remove(userName);
    }
}
 

채팅방 클래스를 entity와 dto로 분리한다.

 

 

  • chatRoomRepository
public interface ChatRoomRepository extends JpaRepository<ChatRoom,String> {
}
 

디비를 연결하기 전에는 service없이 repository에 모든 코드를 때려박았으나 이제는 분리가 필요하다.

 

 

  • chatService
@Log4j2
@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements ChatService{
    private final ChatRoomRepository chatRoomRepository;
    private final MemberRepository memberRepository;
    private final RootConfig rootConfig;
    @Override
    public List<ChatRoomDTO> chatRoomList() {
        List<ChatRoom> chatRoomList = chatRoomRepository.findAll();
        List<ChatRoomDTO> chatRoomDTOS = chatRoomList.stream().map(chatRoom -> new ChatRoomDTO(chatRoom)).collect(Collectors.toList());
        return chatRoomDTOS;
    }

    @Override
    @Transactional
    public ChatRoomDTO createRoom(String roomName) {
        ChatRoom chatRoom = ChatRoom.builder().roomId(UUID.randomUUID().toString()).roomName(roomName).userCount(0).build();
        chatRoomRepository.save(chatRoom);
        return rootConfig.getMapper().map(chatRoom,ChatRoomDTO.class);
    }

    @Override
    public List<String> userList(String roomId) {
        ChatRoom chatRoom = chatRoomRepository.findById(roomId).orElseThrow(() -> new EntityNotFoundException(CHATROOM_NOT_FOUND));
        List<String> users = chatRoom.getUserList().stream().map(user -> user.getMemberId()).collect(Collectors.toList());
        return users;
    }

    @Override
    @Transactional
    public void addUser(String roomId, String userName) {
        ChatRoom chatRoom = chatRoomRepository.findById(roomId).orElseThrow(() -> new EntityNotFoundException(CHATROOM_NOT_FOUND));
        Member user = memberRepository.findByMemberId(userName).orElseThrow(() -> new EntityNotFoundException(MEMBER_NOT_FOUND));
        chatRoom.upUserCount();
        chatRoom.addUser(user);
    }

    @Override
    @Transactional
    public void delUser(String roomId, String userName) {
        ChatRoom chatRoom = chatRoomRepository.findById(roomId).orElseThrow(() -> new EntityNotFoundException(CHATROOM_NOT_FOUND));
        Member user = memberRepository.findByMemberId(userName).orElseThrow(() -> new EntityNotFoundException(MEMBER_NOT_FOUND));
        chatRoom.downUserCount();
        chatRoom.removeUser(user);
    }
}
 
  • chatRoomController
@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/chatroom")
public class ChatRoomController {
    private final ChatService chatService;

    // 채팅 리스트 화면
    @GetMapping("/")
    public ResponseEntity<ResultResponse> chatRoomList(){
        List<ChatRoomDTO> chatRoomDTOS = chatService.chatRoomList();
        return ResponseEntity.ok(ResultResponse.of(GET_CHATLIST_SUCCESS, chatRoomDTOS));
    }

    // 채팅방 생성
    @PostMapping("/room")
    public ResponseEntity<ResultResponse> createRoom(@RequestParam String name) {
        ChatRoomDTO room = chatService.createRoom(name);
        return ResponseEntity.ok(ResultResponse.of(CREATE_CHATROOM_SUCCESS,room.getRoomId()));
    }

    // 채팅에 참여한 유저 리스트 반환
    @GetMapping("/userlist")
    public ResponseEntity<ResultResponse> userList(String roomId) {
        List<String> userList = chatService.userList(roomId);
        return ResponseEntity.ok(ResultResponse.of(GET_CHAT_USERLIST_SUCCESS,userList));
    }
}
 

간단하게 채팅방과 참여유저를 DB로 저장하고 관리할 수 있게 바꾸었다.

 

728x90
반응형