WebRTC Connecting two remote peers using NodeJS , Socket.io

260 Views Asked by At

I have the following server code and frontend react code. I have a server running using ngrok. the server connection is working fine. ICE candidates are also generating. But the video is not exchanging as expected.

I want to connect this two calls exchange automaticaly without adding any reference. How is possible to do that. I can use broadcast option to send the candidate or ICE reference automaticaly.

client react code

import React, { useState, useEffect, useRef } from 'react';
import io from 'socket.io-client';

const socket = io('http://localhost:8000/');

const config = {
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    { urls: 'stun:stun1.l.google.com:19302' },
    { urls: 'stun:stun2.l.google.com:19302' },
    { urls: 'stun:stun3.l.google.com:19302' },
    { urls: 'stun:stun4.l.google.com:19302' },
  ],
};

const App = () => {
  const [peerConnection, setPeerConnection] = useState(null);
  const [localStream, setLocalStream] = useState(null);
  const [remoteStream, setRemoteStream] = useState(null);
  const localVideoRef = useRef();
  const remoteVideoRef = useRef();

  useEffect(() => {
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
      .then(stream => {
        setLocalStream(stream);
        localVideoRef.current.srcObject = stream;
      })
      .catch(error => console.log('Error accessing media devices: ', error));
  }, []);

  useEffect(() => {
    if (peerConnection) {
      peerConnection.onicecandidate = event => {
        if (event.candidate) {
          console.log('Candidate', event.candidate);
          socket.emit('iceCandidate', event.candidate);
        }
      };

      peerConnection.ontrack = event => {
        setRemoteStream(event.streams[1]);
        remoteVideoRef.current.srcObject = event.streams[0];
      };

      socket.on('iceCandidate', candidate => {
        peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
      });

      socket.on('sdp', async sdp => {
        if (sdp.type === 'offer') {
          await peerConnection.setRemoteDescription(new RTCSessionDescription(sdp));
          const answer = await peerConnection.createAnswer();
          await peerConnection.setLocalDescription(answer);
          socket.emit('sdp', answer);
        } else if (sdp.type === 'answer') {
          await peerConnection.setRemoteDescription(new RTCSessionDescription(sdp));
        }
      });
    }
  }, [peerConnection]);

  const createPeerConnection = () => {
    console.log("hello");
    const pc = new RTCPeerConnection(config);
    localStream.getTracks().forEach(track => pc.addTrack(track, localStream));
    setPeerConnection(pc);
  };

  const initiateCall = async () => {
    if (localStream) {
      createPeerConnection();
      const offer = await peerConnection.createOffer();
      await peerConnection.setLocalDescription(offer);
      console.log("offer", offer);
      socket.emit('sdp', offer);
    }
  };

  return (
    <div>
      <video ref={localVideoRef} autoPlay muted width={300}/>
      <video ref={remoteVideoRef} autoPlay />
      <button onClick={initiateCall}>Start Call</button>
    </div>
  );
};

export default App;

server

const express = require('express');
const app = express();
const server = require('http').createServer(app);

const io = require("socket.io")(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"]
  }
});

const PORT = process.env.PORT || 8000;

const peers = {};

io.on('connection', socket => {
  socket.on('sdp', sdp => {
    console.log('sdp',sdp);
    socket.broadcast.emit('sdp', sdp);
  });

  socket.on('iceCandidate', candidate => {
    socket.broadcast.emit('iceCandidate', candidate);
  });

  socket.on('joinRoom', room => {
    socket.join(room);
    peers[socket.id] = room;

    const otherPeers = Object.keys(peers)
      .filter(id => peers[id] === room && id !== socket.id);

    socket.emit('otherPeers', otherPeers);
    socket.broadcast.to(room).emit('newPeer', socket.id);
  });

  socket.on('disconnect', () => {
    const room = peers[socket.id];

    if (room) {
      delete peers[socket.id];
      io.to(room).emit('peerDisconnected', socket.id);
    }
  });
});

server.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

0

There are 0 best solutions below