sns 프로젝트

실시간 채팅 기능 수정하기(실시간 채팅 업데이트)

우주속공간 2024. 1. 24. 23:58

예전에 진행했던 트위터 프로젝트 문서를 블로그에 올리면서 많은 오류를 발생했다. 그래서 최근에 트위터 프로젝트 코드를 다시 고쳐나가 시작했다. 그 중 가장 많이 고쳤던 것은 실시간 채팅 부분이다. 

 

오늘 새로 수정한 부분은 채팅 데이터를 실시간으로 반영해서 화면에 보여지게 하는 코드를 수정한 것이다.

예전의 코드에서는 현재 로그인한 유저가 보낸 메세지만 실시간으로 채팅창에 업데이트 되었지만 이제는 다른 유저가 보낸 메세지도 즉각적으로 업데이트된다.

 

수정된 코드는 다음과 같다. 

처음 채팅 데이터를 받는게 아니라 상대방이 새로운 데이터를 보내면 배열 형태가 아니라 오브젝트 형태로 받게 된다.

-> 이를 활용해서 만약 웹소켓으로 받은 새로운 데이터가 단일 객체일때 새로운 코드 추가

-> 새 데이터 채팅를 보낸 사람이 현재 로그인한 유저가 아닐경우 상대방이 보낸 메세지이기때문에 채팅방 데이터에 반영(만약 로그인 유저가 보낸경우는 따로 반영하는 코드가 있음)

-> 그리고 만약 현재 로그인한 유저가 업데이트된 채팅방 화면을 보고 있을 경우 선택된 채팅방 데이터를 담아둔 상태도 업데이트 시켜서 즉각적으로 보이게 만들었다. 아니라면 새로 추가된 채팅방으로 화면 전환

 

 

   socket.on("RESPOND_DATA", (data: ChatMessage[] | ChatMessage) => {
      let updatedChatRooms = { ...sortedChatRooms };

      // 데이터가 배열인지 단일 객체인지 확인
      if (Array.isArray(data)) {
        // 배열일 경우: 기존 로직 사용
        data.forEach((message) => {
          if (!updatedChatRooms[message.roomId]) {
            updatedChatRooms[message.roomId] = [];
          }
          updatedChatRooms[message.roomId].push(message);
        });
        Object.keys(updatedChatRooms).forEach((roomId) => {
          updatedChatRooms[roomId].sort((a, b) => {
            let dateA = new Date(a.date);
            let dateB = new Date(b.date);
            return dateA.getTime() - dateB.getTime();
          });
        });

        setChatRoomData(updatedChatRooms);
      } else {
      
      // 새롭게 코드가 추가된 부분
        const newData = data;
        // newData와 id의 데이터타입이 달라서 같게 바꿈
        const stringId = id.toString();

        if (newData.send !== stringId) {
          setChatRoomData((prevChatRooms) => {
            // 새 메시지의 roomId를 기반으로 적절한 채팅방 찾기
            const updatedRoom = prevChatRooms[newData.roomId]
              ? [...prevChatRooms[newData.roomId]]
              : [];
            updatedRoom.push(newData);

            // 메시지를 날짜 순으로 정렬
            updatedRoom.sort(
              (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
            );
            // 선택된 채팅방의 메시지 업데이트
            setSelectedMessages(updatedRoom);
            // 유저가 다른 채팅방을 보고 있는 경우 화면 전환이 일어나기때문에 채팅방 정보를 보여주기 위해 업데이트 
            setSelectedRoomId(newData.roomId);

            // 새로운 상태 반환
            return { ...prevChatRooms, [newData.roomId]: updatedRoom };
          });
        }
      }

    });

 

현재 유저가 보고 있는 채팅방이 어딘지 보기 쉽게 알려주기 위해 채팅 화면 맨 위쪽에 현재 선택된 채팅방 이름을 보여주는 부분 추가