개발 기록

220120 springboot 웹소켓으로 채팅 기능 구현 -2 (참여인원 표시) 본문

TIL

220120 springboot 웹소켓으로 채팅 기능 구현 -2 (참여인원 표시)

수염차 2022. 1. 20. 13:56

채팅방 리스트와 채팅방안에 몇명이 참여 중인지 표시하기

 

처음에는 입장하고 퇴장할때 userCount 를 더해주고 빼줬다

이렇게 하니까 채팅방안에서 새로고침할때나 나가기를 안 누르고 뒤로갔다가 다시 들어가면 수가 더해졌다

블로그 찾아봤을때 몇개가 이런 식으로 설명되있던 것 같은데 이렇게 되면 제대로 수를 못 세는 것 같아서

채팅방에 참가한 유저를 저장하는 테이블을 하나 만들어서 진행했다.

 

**

채팅방에 입장하게 되면 입장한 유저를 ChatUser에 저장.

(이미 저장되어 있을 경우는 제외)

userCount는 db에서 해당 채팅방id로 저장되어 있는 유저 데이터 갯수를 반환

 

나가기를 누르게 되면 db에서 삭제

userCount 갱신해서 표시해줌

 

userCount는 메시지가 보내질때 마다 갱신되어 표시되어짐

(입장,퇴장때도 입장,퇴장 메시지가 보내지니까 그때 바뀐다)

 

 

chatRoomService

좀 고쳐야될 부분은 chatUser가 저장되어있는지 확인할때 방법을 db에서 찾을때 없으면 익셉션이 터지면 그걸 이용했다. 더 깔끔한 방법이 있을 것 같다.

@Transactional
    public void enterRoom(ChatMessageDto messageDto) {
        ChatRoom chatRoom = chatRoomRepository.findById(messageDto.getRoomId()).orElseThrow(
                () -> new ApiRequestException("해당 채팅방이 없습니다.")
        );
        User byKakaoId = userRepository.findByKakaoId(messageDto.getSender()).orElseThrow(
                () -> new ApiRequestException("해당 유저가 없습니다.")
        );

        try {
            ChatUser byChatRoomAndUser = chatUserRepository.findByChatRoomAndUser(chatRoom, byKakaoId).orElseThrow(
                    () -> new ApiRequestException("해당 채팅 유저가 없습니다.")
            );
            //메시지 전송
            messagingTemplate.convertAndSend("/sub/chat/room/" + messageDto.getRoomId(), messageDto);

        } catch (ApiRequestException e) {
            //채팅 유저에 저장되어 있지 않을때 ( 처음 입장 )
            chatUserRepository.save(new ChatUser(byKakaoId, chatRoom));
            //인원수 증가
            chatRoom.setUserCount(chatUserRepository.countByChatRoom(chatRoom));
            //메시지 전송
            messagingTemplate.convertAndSend("/sub/chat/room/" + messageDto.getRoomId(), messageDto);
        }
    }

 

클라이언트

채팅방 인원수 가져오는 함수 추가하고 정보가져오는 코드 변경

function onSocket() {
            let socket = new SockJS('/ws-stomp');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function () {
                stompClient.subscribe('/sub/chat/room/' + roomId, function (chat) {
                    //subscribe api에 메시지 날릴때마다 채팅방 인원수 가져오기
                    getUserCount();

                    //메시지 날린사람 정보 가져오기
                    let kakaoId = JSON.parse(chat.body).sender
                    let message = JSON.parse(chat.body).message

                    //카카오 아이디로 유저이름, 사진 가져오기
                    $.ajax({
                        type: "GET",
                        url: `/user/${kakaoId}`,
                        beforeSend: function (xhr) {
                            xhr.setRequestHeader('Authorization', 'Bearer ' + localStorage.getItem('token'));
                        },
                        success: function (response) {
                            username = response['username'];
                            imgLink = response['imgUrl'];
                            //보낸 메시지 나타내기
                            showMsg(response, kakaoId, message);
                        }
                    })
                });
                stompClient.send("/pub/chat/enter", {}, JSON.stringify({
                    'roomId': roomId, 'sender': userOwn, 'message': "채팅 방에 입장했습니다."
                }))
            });
        }

 


 

채팅방 외부랑 내부에 참여인원 표시 끗

Comments