import React, { useState } from "react"; import io from "socket.io-client"; import { useRef } from "react"; import { useEffect } from "react"; import Video from "./Video"; import { useParams } from "react-router-dom"; const Screen = () => { const [socket, setSocket] = useState(null); const [users, setUsers] = useState([]); const { roomId, channelId } = useParams(); let localVideoRef = useRef(null); let sendPC; let receivePCs; // 방화벽 등의 보호장치를 거쳐 ip로 연결하기 위한 설정 const pc_config = { iceServers: [ // { // urls: 'stun:[STUN_IP]:[PORT]', // 'credentials': '[YOR CREDENTIALS]', // 'username': '[USERNAME]' // }, { urls: "stun:stun.l.google.com:19302", }, ], }; useEffect(() => { let newSocket = io.connect("http://localhost:8080"); let localStream; // newSocket.on("userEnter", (data) => { createReceivePC(data.id, newSocket); }); newSocket.on("allUsers", (data) => { let len = data.users.length; for (let i = 0; i < len; i++) { createReceivePC(data.users[i].id, newSocket); } }); newSocket.on("userExit", (data) => { receivePCs[data.id].close(); delete receivePCs[data.id]; setUsers((users) => users.filter((user) => user.id !== data.id)); }); newSocket.on("getSenderAnswer", async (data) => { try { console.log("get sender answer"); console.log(data.sdp); await sendPC.setRemoteDescription(new RTCSessionDescription(data.sdp)); } catch (error) { console.log(error); } }); newSocket.on("getSenderCandidate", async (data) => { try { console.log("get sender candidate"); if (!data.candidate) return; sendPC.addIceCandidate(new RTCIceCandidate(data.candidate)); console.log("candidate add success"); } catch (error) { console.log(error); } }); newSocket.on("getReceiverAnswer", async (data) => { try { console.log(`get socketID(${data.id})'s answer`); let pc = receivePCs[data.id]; await pc.setRemoteDescription(data.sdp); console.log(`socketID(${data.id})'s set remote sdp success`); } catch (error) { console.log(error); } }); newSocket.on("getReceiverCandidate", async (data) => { try { console.log(data); console.log(`get socketID(${data.id})'s candidate`); let pc = receivePCs[data.id]; if (!data.candidate) return; pc.addIceCandidate(new RTCIceCandidate(data.candidate)); console.log(`socketID(${data.id})'s candidate add success`); } catch (error) { console.log(error); } }); setSocket(newSocket); navigator.mediaDevices .getUserMedia({ audio: true, video: { width: 375, height: 260, }, }) .then((stream) => { if (localVideoRef.current) localVideoRef.current.srcObject = stream; localStream = stream; sendPC = createSenderPeerConnection(newSocket, localStream); createSenderOffer(newSocket); newSocket.emit("joinRoom", { id: newSocket.id, roomID: roomId, }); }) .catch((error) => { console.log(`getUserMedia error: ${error}`); }); }, []); const createReceivePC = (id, newSocket) => { try { console.log(`socketID(${id}) user entered`); let pc = createReceiverPeerConnection(id, newSocket); createReceiverOffer(pc, newSocket, id); } catch (error) { console.log(error); } }; const createSenderOffer = async (newSocket) => { try { let sdp = await sendPC.createOffer({ offerToReceiveAudio: false, offerToReceiveVideo: false, }); console.log("create sender offer success"); await sendPC.setLocalDescription(new RTCSessionDescription(sdp)); newSocket.emit("senderOffer", { sdp, senderSocketID: newSocket.id, roomID: roomId, }); } catch (error) { console.log(error); } }; const createReceiverOffer = async (pc, newSocket, senderSocketID) => { try { let sdp = await pc.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true, }); console.log("create receiver offer success"); await pc.setLocalDescription(new RTCSessionDescription(sdp)); newSocket.emit("receiverOffer", { sdp, receiverSocketID: newSocket.id, senderSocketID, roomID: roomId, }); } catch (error) { console.log(error); } }; const createSenderPeerConnection = (newSocket, localStream) => { let pc = new RTCPeerConnection(pc_config); pc.onicecandidate = (e) => { if (e.candidate) { console.log("sender PC onicecandidate"); newSocket.emit("senderCandidate", { candidate: e.candidate, senderSocketID: newSocket.id, }); } }; pc.oniceconnectionstatechange = (e) => { console.log(e); }; if (localStream) { console.log("localstream add"); localStream.getTracks().forEach((track) => { pc.addTrack(track, localStream); }); } else { console.log("no local stream"); } // return pc return pc; }; const createReceiverPeerConnection = (socketID, newSocket) => { let pc = new RTCPeerConnection(pc_config); // add pc to peerConnections object receivePCs = { ...receivePCs, [socketID]: pc }; pc.onicecandidate = (e) => { if (e.candidate) { console.log("receiver PC onicecandidate"); newSocket.emit("receiverCandidate", { candidate: e.candidate, receiverSocketID: newSocket.id, senderSocketID: socketID, }); } }; pc.oniceconnectionstatechange = (e) => { console.log(e); }; pc.ontrack = (e) => { console.log("ontrack success"); setUsers((oldUsers) => oldUsers.filter((user) => user.id !== socketID)); setUsers((oldUsers) => [ ...oldUsers, { id: socketID, stream: e.streams[0], }, ]); }; // return pc return pc; }; return (
{console.log(users)}
); }; export default Screen;