삐옹

React + Socket.io로 여러 개의 채팅방 만들기(1) 본문

React

React + Socket.io로 여러 개의 채팅방 만들기(1)

삐옹 2022. 7. 9. 02:11

내가 구현하고 싶은 채팅 기능의 일부이다.

채팅 할 수 있는 사람들의 리스트가 있다. (A유저, B유저, C유저)
-> A유저를 클릭 시 A유저에게 채팅을 할 수 있다.
-> B유저를 클릭하면 A유저와의 채팅을 끝내고 B유저와 채팅을 할 수 있다.
-> C유저를 클릭하면 B유저와의 채팅을 끝내고 C유저와 채팅을 할 수 있다.

* 실시간이냐고? 오브콜스 와이낫.

 

실행 순서

  1. 서버와 socket.io 연결.
  2. 방에 입장 + 대화목록 불러오기
  3. 불러온 대화목록 화면에 뿌리기
  4. 채팅을 치면 채팅목록에 저장하고 대화목록을 다시 화면에 뿌리기
  5. 지금껏 나눈 채팅을 대화목록에 저장하고 방 떠나기

간략히 말하자면

방 입장 -> 채팅 -> 방 나가기 + (다른) 방 입장 -> 채팅 -> 방 나가기 + (다른) 방 입장 + 채팅 ..

이거다.


서버와 socket.io 연결.

 

import io from "socket.io-client";

const socket = io.connect("http://3.36.74.108");

 

방에 입장 + 대화목록 불러오기

구현순서

  1. 로그인 당사자인 유저 A가 유저B를 클릭하면 둘의 이름을 더해 "AB"라는 방에 입장한다.
  2. 동시에 "AB"방의 채팅목록을 불러온다
 return (
    <>
      <MyChatList>
        {exceptMe() &&
          exceptMe().map((member, idx) => {
            const temp = [member.memberName, userName];
            temp.sort();
            const newRoomName = temp[0] + temp[1]; // 1. 고유한 방이름이 된다
            return (
              <div>
                <UserProfile
                  key={idx}
                  text={member.memberName}
                  roomName={roomName}
                  newRoomName={newRoomName} // 2. 해당 유저의 프로필을 클릭하면  join 이벤트 발동 + 대화 목록 불러오기
                  alignItems={"center"}
                  moveRoom={moveRoom}
                  profileImage={member.profile_image}
                />
                <div className="message-count">
                  <div className="count-alarm"></div>
                  <div className="count-number"></div>
                </div>
              </div>
            );
          })}
      </MyChatList>
    </>
  );

자문자답 QnA

 

Q) 두 사람이 같은 이름의 방에 들어가야하는데 채팅을 하텐데, 방이름을 어떻게 통일시키죠?

방이름은 A가 B에 들어와도 , B가 A에 들어와도 토씨 하나 틀리지 않고 같아야한다. 

그래서 방이름을 사람의 이름을 더한 문자열로 한다고 하면 가나다순으로 이름 두개를 정렬시켰다.

 

Q) 상대방과 처음 말할 때는 아무것도 없을텐데 에러가 뜨지 않을까요?

유저가 처음 로그인을 할 때부터 유저의 정보에,  채팅목록 key값과 빈 배열 value를 담은 채팅목록 객체를 줍니다.

e.g. {user_info : { ... data, chat_list : [] }}

불러온 채팅목록 화면에 뿌리기

구현순서

  1. 유저 A가 채팅을 치면 왼쪽에 말풍선이 추가된다. +채팅목록에 업데이트 
  2. 유저 B가 채팅을 치면 오른쪽에 말풍선이 추가된다. +채팅목록에 업데이트
  // 메시지 보내기
  const sendMessage = async () => {
    if (currentMessage !== "") {
      // 접속한 방 이름, 유저이름, 작성한 메시지, 시간을 담은 data 객체
      const messageData = {
        room: roomName,
        author: username,
        message: currentMessage,
        time:
          new Date(Date.now()).getHours() +
          ":" +
          new Date(Date.now()).getMinutes(),
      };
      // 소켓 명령어와 함께 메시지 데이터를 보낸다
      await currentSocket.emit("send_message", messageData);
      
      // 지금까지의 채팅 리스트 + 추가한 메시지를 더해 state로 저장하고 화면에 뿌려준다
      setMessageList((list) => [...list, messageData]);
      setCurrentMessage("");
    }
  };

자문자답 QnA

Q) 다른 채팅방에 들어갈 때 전에 있던 대화방의 채팅목록은 어떻게 되나요?

채팅방의 이름과 함께 채팅목록이 서버에 저장됩니다.

여기서 채팅방의 이름을 저장하는 이유는 나와 상대방이 고유한 값으로 공유하는 것이 채팅방의 이름이기 때문에

다음번에 두 사람의 채팅목록을 불러올 때는 채팅방의 이름을 조회하여 불러올 수 있다고 생각했습니다.

 


빠른 시일 내로 2부를 준비 해보겠습니다