Posts

Post not yet marked as solved
0 Replies
766 Views
I am having a video chat application using react js in the frontend and i have one SFU server which is based on Node js with WRTC library for supporting webRTC apis in the server side(M87). App.js import React, { useState, useRef, useEffect, useCallback } from "react"; import io from "socket.io-client"; import Video from "./Components/Video"; import { WebRTCUser } from "./types"; const pc_config = { iceServers: [ // { // urls: 'stun:[STUN_IP]:[PORT]', // 'credentials': '[YOR CREDENTIALS]', // 'username': '[USERNAME]' // }, { urls: "stun:stun.l.google.com:19302", }, ], }; const SOCKET_SERVER_URL = "https://192.168.132.29:8080"; const App = () => { const socketRef = useRef<SocketIOClient.Socket>(); ...... .......... const createReceiverPeerConnection = useCallback((socketID: string) => { try { const pc = new RTCPeerConnection(pc_config); // add pc to peerConnections object receivePCsRef.current = { ...receivePCsRef.current, [socketID]: pc }; pc.onicecandidate = (e) => { if (!(e.candidate && socketRef.current)) return; console.log("receiver PC onicecandidate"); socketRef.current.emit("receiverCandidate", { candidate: e.candidate, receiverSocketID: socketRef.current.id, senderSocketID: socketID, }); }; pc.oniceconnectionstatechange = (e) => { console.log(e); }; pc.ontrack = (e) => { console.log("ontrack success"); setUsers((oldUsers) => oldUsers .filter((user) => user.id !== socketID) .concat({ id: socketID, stream: e.streams[0], }) ); }; // return pc return pc; } catch (e) { console.error(e); return undefined; } }, []); ...... ............ return ( <div> <video style={{ width: 240, height: 240, margin: 5, backgroundColor: "black", }} muted ref={localVideoRef} autoPlay /> {users.map((user, index) => ( <Video key={index} stream={user.stream} /> ))} </div> ); }; export default App; server.js let http = require("http"); let express = require("express"); let cors = require("cors"); let socketio = require("socket.io"); let wrtc = require("wrtc"); const fs = require("fs"); let https = require("https"); const port=8080; const options = { key: fs.readFileSync("../cert/cert.priv.key"), cert: fs.readFileSync("../cert/cert.chain.pem"), }; const app = express(); const server = https.createServer(options, app); app.use(cors()); let receiverPCs = {}; let senderPCs = {}; let users = {}; let socketToRoom = {}; const pc_config = { iceServers: [ // { // urls: 'stun:[STUN_IP]:[PORT]', // 'credentials': '[YOR CREDENTIALS]', // 'username': '[USERNAME]' // }, { urls: "stun:stun.l.google.com:19302", }, ], }; const isIncluded = (array, id) => array.some((item) => item.id === id); const createReceiverPeerConnection = (socketID, socket, roomID) => { const pc = new wrtc.RTCPeerConnection(pc_config); if (receiverPCs[socketID]) receiverPCs[socketID] = pc; else receiverPCs = { ...receiverPCs, [socketID]: pc }; pc.onicecandidate = (e) => { //console.log(`socketID: ${socketID}'s receiverPeerConnection icecandidate`); socket.to(socketID).emit("getSenderCandidate", { candidate: e.candidate, }); }; pc.oniceconnectionstatechange = (e) => { //console.log(e); }; pc.ontrack = (e) => { if (users[roomID]) { if (!isIncluded(users[roomID], socketID)) { users[roomID].push({ id: socketID, stream: e.streams[0], }); } else return; } else { users[roomID] = [ { id: socketID, stream: e.streams[0], }, ]; } socket.broadcast.to(roomID).emit("userEnter", { id: socketID }); }; return pc; }; const createSenderPeerConnection = ( receiverSocketID, senderSocketID, socket, roomID ) => { const pc = new wrtc.RTCPeerConnection(pc_config); if (senderPCs[senderSocketID]) { senderPCs[senderSocketID].filter((user) => user.id !== receiverSocketID); senderPCs[senderSocketID].push({ id: receiverSocketID, pc }); } else senderPCs = { ...senderPCs, [senderSocketID]: [{ id: receiverSocketID, pc }], }; pc.onicecandidate = (e) => { //console.log(`socketID: ${receiverSocketID}'s senderPeerConnection icecandidate`); socket.to(receiverSocketID).emit("getReceiverCandidate", { id: senderSocketID, candidate: e.candidate, }); }; pc.oniceconnectionstatechange = (e) => { //console.log(e); }; ... ...... const closeReceiverPC = (socketID) => { if (!receiverPCs[socketID]) return; receiverPCs[socketID].close(); delete receiverPCs[socketID]; }; const closeSenderPCs = (socketID) => { if (!senderPCs[socketID]) return; senderPCs[socketID].forEach((senderPC) => { senderPC.pc.close(); const eachSenderPC = senderPCs[senderPC.id].filter( (sPC) => sPC.id === socketID )[0]; if (!eachSenderPC) return; eachSenderPC.pc.close(); senderPCs[senderPC.id] = senderPCs[senderPC.id].filter( (sPC) => sPC.id !== socketID ); }); delete senderPCs[socketID]; }; const io = socketio.listen(server); io.sockets.on("connection", (socket) => { socket.on("joinRoom", (data) => { try { let allUsers = getOtherUsersInRoom(data.id, data.roomID); io.to(data.id).emit("allUsers", { users: allUsers }); } catch (error) { console.log(error); } }); socket.on("senderOffer", async (data) => { try { socketToRoom[data.senderSocketID] = data.roomID; let pc = createReceiverPeerConnection( data.senderSocketID, socket, data.roomID ); await pc.setRemoteDescription(data.sdp); let sdp = await pc.createAnswer({ offerToReceiveAudio: true, offerToReceiveVideo: true, }); await pc.setLocalDescription(sdp); socket.join(data.roomID); io.to(data.senderSocketID).emit("getSenderAnswer", { sdp }); } catch (error) { console.log(error); } }); socket.on("senderCandidate", async (data) => { try { let pc = receiverPCs[data.senderSocketID]; await pc.addIceCandidate(new wrtc.RTCIceCandidate(data.candidate)); } catch (error) { console.log(error); } }); ..... ......... startServer(port); function startServer(port) { server.listen(port, () => { console.log(`[INFO] Server app listening on port ${port}`); }); }
Posted Last updated
.