1

I am developing a video chat application using React and Express. However, I'm encountering an issue where the "on call" event handler of a new user is not being triggered when they try to connect to an ongoing chat. It seems that despite the other user (who is already inside the chat) initiating the call, the event handler fails to respond.

I have made sure that the user inside the chat only calls the incoming user once the "stream-ready" emit is sent.

Furthermore, I have verified that the peer.call function receives the correct incoming peer ID.

Call Object

bject { _events: {}, _eventsCount: 0, peer: "mt98fbp8zYv7kQcgAABB", provider: {…}, options: {…}, _open: false, metadata: undefined, _localStream: MediaStream, connectionId: "mc_vptcghuz25", _negotiator: {…}, … }
​
_events: Object { stream: {…} }
​​
stream: Object { fn: connectToNewUser(userVideoStream)
, context: {…}, once: false }
​​​
context: Object { _eventsCount: 1, peer: "mt98fbp8zYv7kQcgAABB", _open: false, … }
​​​​
_events: Object { stream: {…} }
​​​​
_eventsCount: 1
​​​​
_localStream: MediaStream { id: "{81b4dc19-bd75-4eb1-bce2-a0f35b992392}", active: true, onaddtrack: null, … }
​​​​
_negotiator: Object { connection: {…} }
​​​​
_open: false
​​​​
connectionId: "mc_vptcghuz25"
​​​​
metadata: undefined
​​​​
options: Object { _stream: MediaStream }
​​​​
peer: "mt98fbp8zYv7kQcgAABB"
​​​​
peerConnection: RTCPeerConnection { _onicecandidate: onicecandidate(e)
, _eventMap: {…}, signalingState: "have-local-offer", … }
​​​​
provider: Object { _eventsCount: 1, _lastServerId: "cqV1NKDzWx2U1NE6AABD", _destroyed: false, … }
​​​​
<prototype>: Object { constructor: l(e, t, o), addStream: addStream(e), handleMessage: handleMessage(e)
, … }
​​​
fn: function connectToNewUser(userVideoStream)
​​​
once: false
​​​
<prototype>: Object { … }
​​
<prototype>: Object {  }
​
_eventsCount: 1
​
_localStream: MediaStream { id: "{81b4dc19-bd75-4eb1-bce2-a0f35b992392}", active: true, onaddtrack: null, … }
​​
active: true
​​
id: "{81b4dc19-bd75-4eb1-bce2-a0f35b992392}"
​​
onaddtrack: null
​​
onremovetrack: null
​​
<prototype>: MediaStreamPrototype { getAudioTracks: getAudioTracks(), getVideoTracks: getVideoTracks(), getTracks: getTracks(), … }
​
_negotiator: Object { connection: {…} }
​
_open: false
​
connectionId: "mc_vptcghuz25"
​
metadata: undefined
​
options: Object { _stream: MediaStream }
​
peer: "mt98fbp8zYv7kQcgAABB"
​
peerConnection: RTCPeerConnection { _onicecandidate: onicecandidate(e)
, _eventMap: {…}, signalingState: "have-local-offer", … }
​
provider: Object { _eventsCount: 1, _id: "cqV1NKDzWx2U1NE6AABD", _destroyed: false, … }
​
<prototype>: Object { constructor: l(e, t, o), addStream: addStream(e), handleMessage: handleMessage(e), … }

.

useOnPeerEvents.js

import Peer from 'peerjs';
import { useEffect, useRef, useState } from 'react';
import { useAppSettingsContext } from '../context/appSettingsContext';
import { useSocket } from '../context/socketContext';
import { removeStream, connectToNewUser, answerCall } from '../utils/peerHelpers'; 
import useStreamTrackProps from './useStreamTrackProps';

export default function useOnPeerEvents( ) {

    const socket                  = useSocket()
    const streamRef               = useRef( null );
    const { room }                = useAppSettingsContext()
    const roomId                  = room[ 'id' ]
    const [ streams, setStreams ] = useState( [] )
    const currentId               = socket.id
    
    useStreamTrackProps( streamRef )
    
    useEffect( () => {

        const host = process.env.REACT_APP_SERVER_HOST || window.location.hostname
        const port = process.env.REACT_APP_SERVER_PORT || window.location.port
        const peer = new Peer( socket.id , { path: '/peerjs', host , port } );

        navigator.mediaDevices.getUserMedia( { audio: true, video: true } )
        .then( stream => {
        
            streamRef.current = stream

            setStreams( streams => [ ...streams, { stream: streamRef.current, id: currentId } ] )

            peer.on( 'call', ( call ) => { answerCall( call, streamRef, setStreams ) } )

            socket.on( 'stream-ready', ( id ) => {  connectToNewUser( id, streamRef.current, peer, setStreams ) })
            
            socket.on( 'left-room', ( peerId ) => { removeStream( peerId, setStreams ) })

            socket.emit( 'stream-ready', roomId )

            console.log( 'stream-ready' , peer.id );
        } )
        
        return () => {

            socket.off( 'left-room' )
            socket.off( 'stream-ready' )
        }
      
    }, [ currentId, roomId, socket ])

    return{ streams }  
}

peerHelpers.js

const addStream = ( newStream, id, setStreams ) => {

    setStreams( streams => { 

        if ( ! streamExists( streams , newStream ) ) {

            return [ ...streams, { stream: newStream, id } ]    
        }
        
        return streams
    })

}

//Removes stream 
const removeStream = ( id, setStreams ) =>  {

    setStreams( ( streams ) => streams.filter( stream => stream[ 'id' ] !== id )  );

}

//Call new user and add his stream
const connectToNewUser = ( id, stream, peer, setStreams ) => {
    console.log( 'connecting...', id, stream  );
    const call = peer.call( id, stream )
    console.log( call );
    call.on( 'stream', ( userVideoStream ) => {
        console.log( 'add');
       addStream(  userVideoStream, id, setStreams  )
    })
}

//Checks if the given stream exists
const streamExists = ( streams, newStream ) => {

    let exists = false
    streams.forEach( stream => {

        if( stream[ 'stream' ].id === newStream.id){
            exists = true
        }
    })

    return exists
}

const answerCall = ( call, stream, setStreams ) => {
    console.log( 'answering...');
    call.answer( stream.current );
    call.on('stream', ( userVideoStream ) => {
        
        addStream( userVideoStream, call[ 'peer' ], setStreams )
    });
}

export {
    connectToNewUser,
    addStream,
    streamExists,
    removeStream,
    answerCall
}

0 Answers0