The problem is the user already in the room can access the other user's vid, but not vice versa. I guess this is signalling issue, and im not able to track it down. Please do help me here. Thanks in advance.

Signalling server:
const express = require("express");
const { createServer } = require("node:http");
const crypto = require("crypto");
const app = express();
const server = createServer(app);

const io = require("socket.io")(server, {
  cors: {
    origin: "*",
  },
});

let rooms = {};

io.on("connection", (socket) => {
  socket.emit("getId", { id: socket.id });

  socket.on("getMeetLink", (data) => {
    const roomId = crypto.randomUUID();
    rooms[roomId] = [];
    console.log(rooms);
    io.to(data.id).emit("meetLink", { roomId });
  });

  socket.on("joinRoom", (data) => {
    socket.join(data.roomId);
    io.to(data.id).emit("onJoinRoom", {
      message: "success",
    });

    socket.to(data.roomId).emit("someone-joining-room", {
      signalData: data.signalData,
      id: data.id,
    });
  });

  socket.on("accept-peer", (data) => {
    io.to(data.id).emit("acceptConnection", { signalData: data.signalData });
  });

  socket.on("sendMessage", (data) => {
    socket.to(data.roomId).emit("incomingMessage", { message: data.message });
  });

  socket.on("disconnect", () => {
    console.log("user disconnected");
  });
});

server.listen(8000, () => {
  console.log("Server running on port", 8000);
});

Client side code:

import React, { useRef, useEffect, useState } from "react";
import {
  Box,
  Button,
  Card,
  CardContent,
  IconButton,
  Input,
  TextField,
} from "@mui/material";
import { MicOff, Mic, Videocam, VideocamOff } from "@mui/icons-material";
import io from "socket.io-client";
import Peer from "simple-peer";
// import {} from "@mui/";

const socket = io.connect("http://localhost:8000");
const HomePage = () => {
  const [videoEnabled, setVideoEnabled] = useState(false);
  const [audioEnabled, setAudioEnabled] = useState(false);
  const [id, setId] = useState(null);
  const [roomId, setRoomId] = useState("");
  const [inRoom, setInRoom] = useState(false);
  const [message, setMessage] = useState("");
  const [myStream, setMyStream] = useState();
  const videoRef = useRef(null);
  const mediaStreams = useRef([]); // Store media streams for cleanup
  const secondVideo = useRef(null);
  const userVideo = useRef();
  const connectionRef = useRef();
  const incomingVids = [];
  useEffect(() => {
    socket.on("getId", (data) => {
      setId(data.id);
      console.log(data.id);
    });

    socket.on("incomingMessage", (data) => {
      console.log(data);
    });

    socket.on("someone-joining-room", (data) => {
      console.log("someOneJoing the room", data);
      const peer = new Peer({
        initiator: false,
        trickle: false,
        stream: myStream,
      });
      peer.on("signal", (signalData) => {
        console.log("sending the signal data back.");
        socket.emit("accept-peer", { signalData: signalData, id: data.id });
      });
      peer.on("stream", (stream) => {
        console.log("someone stream", stream);
        userVideo.current.srcObject = stream;
        incomingVids.push({ stream, id: data.id });
        console.log(incomingVids);
      });

      peer.signal(data.signalData);

      connectionRef.current = peer;
    });
  }, []);

  const getMeetLink = () => {
    console.log("getting meet link");
    socket.emit("getMeetLink", { id });
    socket.on("meetLink", (data) => {
      console.log(data);
      setRoomId(data.roomId);
    });
  };

  const handleInputChange = (event) => {
    setRoomId(event.target.value);
  };

  const handleSetMessageChange = (event) => {
    setMessage(event.target.value);
  };

  const hanndleJoinRoom = () => {
    console.log({ roomId, id });
    const peer = new Peer({
      initiator: true,
      trickle: true,
      stream: myStream,
    });
    peer.on("signal", (data) => {
      console.log("joining room", { roomId, id, signalData: data });
      socket.emit("joinRoom", { roomId, id, signalData: data });
      socket.on("onJoinRoom", (data) => {
        // console.log(data);
        if (data.message == "success") {
          setInRoom(true);
        }
      });
    });

    socket.on("acceptConnection", (vals) => {
      console.log("connection got accepted");
      console.log("Data ", vals);
      peer.signal(vals.signalData);
      peer.on("stream", (stream) => {
        console.log("i joined stream ", stream);
        userVideo.current.srcObject = stream;
      });
    });

    connectionRef.current = peer;
  };

  useEffect(() => {
    // Cleanup function to stop media streams when the component unmounts
    return () => {
      mediaStreams.current.forEach((stream) => {
        stream.getTracks().forEach((track) => track.stop());
      });
    };
  }, [mediaStreams]);

  const handleSendMessage = () => {
    socket.emit("sendMessage", { roomId, message });
  };

  const handleVideoToggle = async () => {
    if (!videoEnabled) {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          video: true,
        });

        setVideoEnabled(true);
        setMyStream(stream);
        mediaStreams.current.push(stream);
        videoRef.current.srcObject = stream;
        videoRef.current.play();
      } catch (error) {
        console.error("Error accessing video:", error);
        setVideoEnabled(false);
      }
    } else {
      const videoStream = mediaStreams.current.find(
        (stream) => stream.getVideoTracks().length > 0
      );
      if (videoStream) {
        videoStream.getTracks().forEach((track) => track.stop());
        videoRef.current.pause();
        videoRef.current.srcObject = null;
        mediaStreams.current = mediaStreams.current.filter(
          (stream) => stream !== videoStream
        );
        setVideoEnabled(false);
      }
    }
  };

  const handleAudioToggle = async () => {
    if (!audioEnabled) {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: true,
        });
        setAudioEnabled(true);
        mediaStreams.current.push(stream);
      } catch (error) {
        console.error("Error accessing audio:", error);
        setAudioEnabled(false);
      }
    } else {
      const audioStream = mediaStreams.current.find(
        (stream) => stream.getAudioTracks().length > 0
      );
      if (audioStream) {
        audioStream.getTracks().forEach((track) => track.stop());
        mediaStreams.current = mediaStreams.current.filter(
          (stream) => stream !== audioStream
        );
        setAudioEnabled(false);
      }
    }
  };

  //   useEffect(() => {
  //     handleAudioToggle();
  //     handleAudioToggle();
  //   }, []);

  return (
    <div
      style={{
        display: "flex",
        // flexDirection: "column",
        alignItems: "center",
        justifyContent: "center",
        height: "100vh",
      }}
    >
      <Card
        style={{
          display: "flex",
          height: "70vh",
          width: "90%",
          // justifySelf: "center",
        }}
        elevation={10}
      >
        <div style={{ flexGrow: 2, margin: "20px" }}>
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              width: "100%",
              height: "100%",
            }}
          >
            <div style={{ display: "flex" }}>
              <video
                style={{
                  // zIndex: 0,
                  width: "calc(50% + 2px)",
                  transform: "scaleX(-1)",
                  height: "80%",
                }}
                playsInline
                muted
                ref={videoRef}
                autoPlay
              ></video>
              <video
                style={{
                  // zIndex: 0,
                  width: "calc(50% + 2px)",
                  transform: "scaleX(-1)",
                  height: "80%",
                }}
                playsInline
                muted
                ref={userVideo}
                autoPlay
              ></video>
            </div>
            <div
              style={{
                height: "20%",
                // backgroundColor: "green",
                display: "flex",
                justifyContent: "center",
                alignItems: "center",
                justifyContent: "space-evenly",
              }}
            >
              <div>
                <IconButton onClick={handleVideoToggle}>
                  {videoEnabled ? <Videocam /> : <VideocamOff />}
                </IconButton>
              </div>
              <div>
                <IconButton onClick={handleAudioToggle}>
                  {audioEnabled ? <Mic /> : <MicOff />}
                </IconButton>
              </div>
            </div>
          </div>
        </div>
        <div style={{ margin: "20px" }}>
          <Card
            style={{ height: "100%", width: "100%", padding: "5px" }}
            elevation={5}
          >
            <CardContent
              style={{
                display: "flex",
                flexDirection: "column",
                justifyContent: "space-evenly",
                alignItems: "center",
                margin: 0,
                padding: 0,
                height: "100%",
              }}
            >
              {!inRoom && (
                <>
                  <div style={{ display: "flex", flexDirection: "column" }}>
                    <TextField
                      id="filled-basic"
                      label="Email"
                      margin="0"
                      variant="filled"
                    />
                    <TextField
                      id="filled-basic"
                      label="Room code"
                      margin="0"
                      variant="filled"
                      value={roomId}
                      onChange={handleInputChange}
                    />
                  </div>
                  <Button
                    variant="contained"
                    style={{ width: "90%" }}
                    onClick={hanndleJoinRoom}
                  >
                    Join
                  </Button>
                  <Button
                    variant="contained"
                    style={{ width: "90%" }}
                    onClick={getMeetLink}
                  >
                    Create Room
                  </Button>
                </>
              )}

              {inRoom && (
                <>
                  <div>{roomId}</div>
                  <Input
                    value={message}
                    onChange={handleSetMessageChange}
                  ></Input>
                  <Button
                    variant="contained"
                    style={{ width: "90%" }}
                    onClick={handleSendMessage}
                  >
                    Send Message
                  </Button>
                </>
              )}
            </CardContent>
          </Card>
        </div>
      </Card>
    </div>
  );
};

export default HomePage;

I tried to debug the signalling data exchange by logging the signal data.

console.log("connection got accepted");
      console.log("Data ", vals);

this does log, but the next peer.on("stream") has no logs.

0

There are 0 best solutions below