미소를뿌리는감자의 코딩

[Aper] 채팅방 형성 과정에 대한 고찰 본문

프로젝트

[Aper] 채팅방 형성 과정에 대한 고찰

미뿌감 2024. 10. 29. 23:20
728x90

1. 개요

이번에 채팅방을 생성함과 더불어서, 시스템 메시지를 보내야 했다.

 

예를 들면 학생이 튜터에게 

' 안녕하세요 작가님. 혹시 가능하시다면, 제 글의 퇴고에 도움을 주실 수 있을까요? ' 와 같이 메시지를 보낸 후,

시스템 메시지로 ' 1:1 수업 요청이 도착했어요. 000님과 1:1 수업을 진행할까요?' 를 보내야 한다.

 

기존에, 채팅방 아이디와 유저 아이디를 받아서 채팅방을 생성하는 것에서 

채팅방을 형성하고, 채팅방에 메시지를 넣는 과정을 포함시키게 되었다.

그 과정에서 mongosh를 사용하게 되었고, Mono와 같은 비동기 처리를 포함시키게 되었다.

 

2. 본문

우선, MainChatController.java 안에 있는 createChat 메서드의 내용은 아래와 같다.

    @PostMapping("/chat")
    public Mono<ResponseDto<Void>> createChat(
            @RequestBody CreateChatRequestDto createChatRequestDto,
            @AuthenticationPrincipal UserDetailsImpl userDetails) {
        Long userId = userDetails.user().getUserId();
        Long tutorId = createChatRequestDto.getTutorId();

        // 비동기적으로 이미 생성된 채팅방인지 확인
        return mainChatService.isCreatedChat(userId, tutorId)
                .flatMap(isCreated -> {
                    if (isCreated) {
                        return Mono.just(ResponseDto.fail("이미 생성된 채팅방 입니다."));
                    }
                    // 채팅방 생성 요청
                    return mainChatService.createChat(userId, tutorId, createChatRequestDto.getMessage());
                });
    }

 

@ResponseBody로 튜터의 id와 요청 메시지를 받아왔다.

채팅방의 형성 유무를 확인하고, 생성되지 않았다면 mainChatService.createChat으로 채팅방을 형성해 주었다.

 

다음으로는 MainChatService.java로, createChat 서비스 코드를 확인할 수 있다.

    @Transactional
    public Mono<ResponseDto<Void>> createChat(Long userId, Long tutorId, String message) {
        ChatRoom chatRoom = new ChatRoom();

        User user = findByIdAndCheckPresent(userId, false);
        User tutor = findByIdAndCheckPresent(tutorId, true);

        ChatParticipant userChatParticipant = new ChatParticipant(chatRoom, user, false);
        ChatParticipant tutorChatParticipant = new ChatParticipant(chatRoom, tutor, true);

        chatRoomRepository.save(chatRoom);
        chatParticipantRepository.save(userChatParticipant);
        chatParticipantRepository.save(tutorChatParticipant);

        return sendSystemMessage(chatRoom.getId(), message, userId, user.getPenName())
                .thenReturn(ResponseDto.success("성공적으로 채팅방을 생성하였습니다."));
    }

chatParticipant에 채팅방과 유저에 대한 정보를 포함해서 entity에 저장을 해주었다.

이후 sendSystemMessage라를 메서드를 통해, 유저가 요청했던 메시지와 채팅방 관련 메시지를 채팅방에 저장해 주었다.

 

private Mono<Void> sendSystemMessage(Long chatRoomId, String message, Long userId, String userPenName) {
    MessageDto userRequestMessage = new MessageDto(chatRoomId, message, userId, 0L);
    Mono<ChatMessage> userMessageMono = chatService.saveMessage(userRequestMessage);

    String serviceMessage = String.format("1:1 수업 요청이 도착했어요. %s님과 1:1 수업을 진행할까요?", userPenName);
    MessageDto systemRequestMessage = new MessageDto(chatRoomId, serviceMessage, 0L, 1L);

    return userMessageMono
            .then(chatService.saveMessage(systemRequestMessage))
            .then();
}

위와 같이 해당 채팅방 아이디에 대해 메시지를 보내주었다.

 

조금 complicate 했던 부분은, Mono, Flux와 같은 비동기 처리를 해주어야 했다는 점이다.

이에, 추후에 front에서 해당 요청을 보내고 처리할 때, 비동기 반환을 처리해 주어야 하기에 조금 복잡해 진다.

 

3. 개선점

개선을 할 부분으로는 메시지를 Enum 처리를 해서, 코드의 가독성을 올리고 싶다.

또한, PostMan 으로 비동기 메시지에 대한 테스트를 할 수 있는지는 모르겠지만, 새로이 작성한 코드에 대한 테스트를 진행하고 싶고 해야 한다... 정 안되면 내가 프론트 스켈레톤 코드를 작성해서 테스트를 할 것이다. -> 내일..!

 

728x90