Spring/Spring Stomp

[Stomp] Spring Boot with React 채팅 서버 : 2. ChatRoomController

noahkim_ 2022. 3. 2. 01:09

1번에서 entity 객체를 만들었으니 이제 chatroom controller 를 만들겠습니다.

생성, 정보 요청, 리스트 전달 등의

1. 채팅방 생성

  • 기본적으로 DM은 1:1 채팅방으로 구현되었습니다.
    (인스타그램, 페이스북 메신저를 따라 만들려고 하였습니다)

1. 개인 DM 을 위한 방 생성

  • 인스타그램이나 페이스북 처럼 해당 사용자에게 DM을 보내고자 할 경우, 프로필에 가서 "사용자와 채팅" 버튼 누르기
  • "사용자와 채팅" 버튼을 누를 시, roomMakerId는 누른 사람의 Id이고, guestId는 해당 프로필 계정의 Id입니다.
  • 채팅방을 먼저 생성한 후, 사용자들을 해당 채팅방의 Member로 저장합니다.
@PostMapping("/personal") // 개인 DM방 생성
public HcsResponse createPersonalChatRoom(@RequestParam("roomMakerId") long roomMakerId, @RequestParam("guestId") long guestId) {

    User roomMaker = userService.findById(roomMakerId);
    User guest = userService.findById(guestId);

    ChatRoom newRoom = ChatRoom.create();

    newRoom = chatRoomService.createChatRoomForPersonal(newRoom, roomMaker, guest);

    return HcsResponse.of(submit.chatRoom(newRoom.getId(), roomMakerId, guestId));
}

 

2. 중고거래 판매자와의 채팅을 위한 DM 방 생성

  • 현재 진행중인 서비스에서 중고거래 게시판이 구현되어 있습니다.
    해당 기능에서 채팅을 할 수 있도록 "판매자와 채팅" 버튼을 제공합니다.
  • 위의 로직과 requestParam 이름만 다를뿐 완전히 동작이 같습니다.
@PostMapping("/tradePost") // 중고거래 판매자에게  채팅을 위해 DM방 생성
public HcsResponse createTradeChatRoom(@RequestParam("buyerId") long buyerId, @RequestParam("tradePostId") long tradePostId) {

    Long sellerId = tradePostService.findAuthorIdById(tradePostId);

    User seller = userService.findById(sellerId);
    User buyer = userService.findById(buyerId);

    ChatRoom newRoom = ChatRoom.create();

    newRoom = chatRoomService.createChatRoomForPersonal(newRoom, seller, buyer);

    return HcsResponse.of(submit.chatRoom(newRoom.getId(), sellerId, buyerId));
}

 

2. 채팅방 정보 요청

  • 채팅방에 사용자가 접속할 경우 방정보를 프론트에 뿌려주는 컨트롤러를 만듭니다.
  • 모든 채팅방의 채팅내역을 뿌릴수는 없으므로 최신 15개만 뿌려줍니다. 
@GetMapping("/")
public HcsResponse ChatRoomInfo(@RequestParam("roomId") String roomId) {
    // 15개만 채팅내역 보내주기
    ChatRoom chatRoom = chatRoomService.findById(roomId);
    ChatRoomInfoDto chatRoomInfoDto = modelMapper.map(chatRoom, ChatRoomInfoDto.class);

    List<ChatMessage> latestChatMessages = chatMessageService.findChatMessagesWithPaging(1, roomId);
    List<ChatMessageInfoDto> chatMessageInfoDtos = new ArrayList<>();

    for (ChatMessage chatMessage : latestChatMessages) {
        ChatMessageInfoDto info = modelMapper.map(chatMessage, ChatMessageInfoDto.class);

        chatMessageInfoDtos.add(info);
    }

    chatRoomInfoDto.setLatestChatMessages(chatMessageInfoDtos);
    return HcsResponse.of(info.chatRoom(chatRoomInfoDto));
}
  • chatMessageService.findChatMessagesWithPaging(1, roomId)
    • JpaRepository의 pagable api를 사용하여 해당 채팅방의 채팅메시지를 15개 가져옵니다.
  • 이후 채팅목록에서 스크롤을 올릴경우 (단일 요청으로) 서버에 현재 채팅 내역 이후 30 채팅내역을 요청합니다.
    (
    해당 기능은 HTTP 요청이 아닌 웹소켓 요청을 하여 실시간으로 받아야 합니다) (추후 구현 예정)

 

3. 채팅방 리스트

  • 채팅목록을 messenger 화면 왼쪽에 보여주어야 하므로 목록 요청 controller 를 생성합니다.
  • 사용자의 전체 채팅목록중 채팅방의 lastChatMessage가 가장 최신인 7개의 방을 리턴해줍니다.
  • 이후 아래로 화면을 스크롤하면 단일요청하여 7개씩 최신 방들을 리턴해줍니다
    (해당 기능은 HTTP 요청이 아닌 웹소켓 요청을 하여 실시간으로 받아야 합니다) (추후 구현 예정)
@GetMapping("/list")
public HcsResponse getChatRoomList(@RequestParam("userId") long userId) {
    // 채팅방 리스트 7개 전달
    int page = 1;
    List<ChatRoom> chatRooms = chatRoomService.findChatRoomsWithPaging(page, userId);
    List<ChatRoomInfoDto> chatRoomInfoDtos = new ArrayList<>();

    for (ChatRoom chatRoom : chatRooms) {
        ChatRoomInfoDto info = modelMapper.map(chatRoom, ChatRoomInfoDto.class);
        chatRoomInfoDtos.add(info);
    }

    ChatRoomListDto chatRoomListDto = ChatRoomListDto.builder()
            .page(page)
            .count(chatRooms.size())
            .reqUserId(userId)
            .chatRooms(chatRoomInfoDtos)

            .build();

    return HcsResponse.of(list.chatRoom(chatRoomListDto));
}