[TIL] WebRtc를 사용한 P2P 통신 (2/2) 23.08.24

이상훈·2023년 8월 25일
0

[내일배움캠프]

목록 보기
58/68

송수신자가 room에 입장하면 welcome으로 이동하며, chat기능을 위해 data channel을 생성하고 offer를 생성함

socket.on('welcome', async (roomName) => {
  try {
    makeConnection(roomName);
    myDataChannel = myPeerConnection.createDataChannel('chat');
    myDataChannel.addEventListener('message', addMessage);

    const offer = await myPeerConnection.createOffer();
    myPeerConnection.setLocalDescription(offer);
    socket.emit('sendOffer', { offer, roomName });
  } catch (err) {
    console.log(err);
  }
});
function handleIce(data, roomName) {
  socket.emit('sendIce', { data: data.candidate, roomName });
  console.log('send ice');
}

function handleAddStream(data) {
  try {
    console.log('스트림', myPeerConnection);
    const peerVideo = document.querySelector('#peer-video');
    const peerStream = data.streams[0];
    peerVideo.srcObject = peerStream;
    console.log('peer와 스트림 연결');
    console.log('peers', data);
    console.log('peers', peerVideo.srcObject);
    console.log('my', myStream);
  } catch (err) {
    console.error(err);
  }
}

function makeConnection(roomName) {
  myPeerConnection = new RTCPeerConnection({
    iceServers: [
      {
        urls: [
          'stun:stun.l.google.com:19302',
          'stun:stun1.l.google.com:19302',
          'stun:stun2.l.google.com:19302',
          'stun:stun3.l.google.com:19302',
          'stun:stun4.l.google.com:19302',
        ],
      },
    ],
  });
  myPeerConnection.addEventListener('icecandidate', (event) => {
    console.log('아이스 이벤트 발생');
    if (event.candidate) {
      handleIce(event.candidate, roomName);
    }
  });
  myPeerConnection.addEventListener('track', handleAddStream);
  myStream.getTracks().forEach((track) => myPeerConnection.addTrack(track, myStream));
}

스트림을 추가할 때 원래는 addStream을 사용했으나 더이상 사용하지 않는 방법으로 권장하지 않는다고하여 track으로 변경하여 사용

송신자가 offer를 전송하면 수신자는 해당 offer의 SDP를 바탕으로 Answer를 작성하고 송신자에게 전달

socket.on('receiveOffer', async (offer) => {
  const remoteOffer = new RTCSessionDescription({
    type: 'offer',
    sdp: offer.payload.sdp,
  });
  if (myPeerConnection.signalingState === 'stable') {
    try {
      await myPeerConnection.setRemoteDescription(remoteOffer);

      const answer = await myPeerConnection.createAnswer();
      await myPeerConnection.setLocalDescription(answer);
      socket.emit('sendAnswer', { answer, roomName: offer.roomName });
    } catch (error) {
      console.error('SDP 파싱 오류', error);
    }
  } else {
    console.log('stable 상태가 아님');
  }
});


수신자의 mediaStream이 된것으로 보이지만 화면 출력이 진행되지 않는 문제가 발생


동영상이 로드 되고있지 않는 문제가 있어 코드를 다시 한번 살펴보았는데


두 브라우저간 연결이 잘 되었다면 connectionState와 iceConnetionState가 "connected"로 변경되어야하는데 현재 상태를 보니 연결이 되지 않은 것으로 보임

socket.on('welcome', async (roomName) => {
  try {
    makeConnection(roomName);
    myDataChannel = myPeerConnection.createDataChannel('chat');
    myDataChannel.addEventListener('message', addMessage);

    const offer = await myPeerConnection.createOffer();
    myPeerConnection.setLocalDescription(offer);
    socket.emit('sendOffer', { offer, roomName });
  } catch (err) {
    console.log(err);
  }
});

이쪽 코드를 console로 찍어보니 offer를 peer A 즉 송신자가 peer B 수신자에게 보내야 하는데 둘 다 offer를 보내고 있음
-> 아직 명확하게 개념이 잡히지 않아 이 부분이 문제인가 싶기도 함


프로젝트 마감기한이 얼마 남지 않아 멤버십과 결제 기능을 먼저 도입해야 하므로 추후 다시 해결해 볼 예정

profile
코린이

0개의 댓글