카테고리 없음

Til (2023.03.02)

prdg 2023. 3. 5. 14:34

socket.io 친구 개인 채팅 1

 

어제 했던 세팅에 추가해서 작업을 했다.

우선 친구를 우클릭을하면 1대1 채팅을 클릭해 넘어갈 수 있는 구조로 만들고 싶었다.

1. 유저 정보 전달

 

우선 상대와 socket으로 방을 친구별로 각각 만들어 통신하려면 상대의 고유 socket id를 알아내야 했다.

상대의 고유 socket id를 알아내기 위해 실행할때 id를 가져오고 그 socket id가 누구의 것인지 구분할 필요도 있었다.

처음에 useEffect로 서버에 각자 자신의 id와 socket id를 보낸다.

  useEffect(() => {
    socket.emit("nickName", myId, socket.id);
  }, []);

server.js에서 받은 후 고유유저아이디/소켓아이디 의 구조로 만든후 배열에 넣어주고 다시 프론트로 가져왔다.

이렇게 하면 유저가 접속해서 로그인 할때 마다 고유유저아이디/소켓아이디가 배열에 추가된 후

wsServer.sockets.emit으로 모두에게 가져다 주게 된다.

그런데 한 아이디가 계속 접속할 경우 배열에 똑같은id가 계속 추가되는 문제가 생길 수 있다.

그래서 접속할때 filter로  배열에서 자신의 id/socket.id를 제거후 다시 새로운 정보를 추가해 돌려주게 했다.

let userSocketId = [];

socket.on("nickName", (myId, id) => {
    socket["nickname"] = `${myId}/${id}`;
    let newUserSocketId = userSocketId.filter((i) => {
      if (i.split("/")[0] === myId) {
        return;
      } else {
        return i;
      }
    });
    newUserSocketId.push(socket["nickname"]);
    userSocketId = newUserSocketId;

    wsServer.sockets.emit("userId", userSocketId);
  });

그리고 받은 친구 정보는 useState를통해 전달해서 사용하였다.

  const [userId, setUserId] = useState([]);
  
  socket.on("userId", (id) => {
    setUserId(id);
  });

 

이제 1대1 채팅을 클릭하는 곳에 onClick을 생성해준 후 이벤트를 만든다.

클릭하면 클릭한 유저의 id를 불러와 위에서 가져온 친구정보가 모두담긴 userid에서 find로 찾는다.

이제 소켓 방을 만들어야 하는데 방 이름은 서로 이렇게 했을때 방이 중복으로 또 생기는걸 방지하기위해 상대방의 id + 내 id를 number로 바꿔준후 했다.

그리고 server로 클릭한 친구의 id/socketId와 만든 방 이름을 보내줬다.

보내주고 유저는 navigate를 사용해 roomName으로만든 채팅방 컴포넌트로 보내줬다.

<ContextMenuP onClick={() => ChatOnClick(id)}>1대1 채팅</ContextMenuP>
//클릭할 컴포넌트 onClick

  const ChatOnClick = (id: string) => {
    //선택한 아이디 불러오기
    const clickId = userId.find((i: string) => {
      return i.split("/")[0] === id;
    });
    //선택한 아이디와 내아이디 더하기 (방이름)
    const roomName = parseInt(clickId.split("/")[0]) + parseInt(myId);

    socket.emit("friendChat", clickId, roomName);
    navigate(`/testchat/:${roomName}`);

    setLayoutMenu("close");
  };

server에선 만든 roomName으로 방을 생성해 join하게 해줬고

가져온 친구 socketid도 wsServer.in을 이용해 친구도 강제로 방에 join하게 해줬다.

이렇게 되면 친구랑 1대1 채팅 방이 연결 되게 된다.

  socket.on("friendChat", (clickId, roomName) => {
    console.log(clickId, roomName);
    socket.join(roomName);
    wsServer.in(clickId.split("/")[1].toString()).socketsJoin(roomName);
  });

 

나머지 설명은 (https://prdg.tistory.com/75) 에 이어서 정리했다.