feross / simple-peer

📡 Simple WebRTC video, voice, and data channels
MIT License
7.36k stars 972 forks source link

Close and restart peer #417

Closed chlamy closed 5 years ago

chlamy commented 5 years ago

Hi, I have tried to create a video conference with open and close events without refresh page but I have this errors :

This is part of my code

function startPeer(initiator) {
    navigator.mediaDevices.getUserMedia({
        video: true,
//        audio: true
    })
    .then(function (stream) {
        console.log('new peer');
        p = new SimplePeer({
            initiator: initiator,
            stream: stream,
            trickle: true,
            config: servers
        });

        p.on('error', function (err) {
            console.log(err);
        });

        p.on('signal', function (data) {
            sendVideoAddress(JSON.stringify(data));
        });

        p.on('stream', function (stream) {
            var video = document.querySelector('#videoD');
            otherStream = stream;
            video.srcObject = stream;
            video.onloadedmetadata = function (e) {
                video.play();
            };
        });

        p.on('close', function () {
            console.log('close');
        });

        var video = document.querySelector('#videoM');
        myStream = stream;
        video.srcObject = stream;
        video.onloadedmetadata = function (e) {
            video.play();
        };
        treatCandidates();
    })
    .catch(function (err) {
        console.log(err.name + ": " + err.message);
    });
}

function addCandidate(candidate) {
    candidates.push(candidate);
    treatCandidates();
}

function treatCandidates() {
    if(p) {
        for (var i=0; i<candidates.length; i++) {
            p.signal(candidates[i]);
        }
        candidates = [];
    }
}

function endCall() {
    p.destroy();
    if(myStream) {
        myStream.getTracks().forEach( (track) => {
            track.stop();
        });
    }
//    if(otherStream) {
//        otherStream.getTracks().forEach( (track) => {
//            track.stop();
//        });
//    }
//    p = null;
    modalCall.modal('hide');
    clearInterval(timerCall);
}

Thanks for your help :)

t-mullen commented 5 years ago

The first error means that you're calling p.signal() after the peer has already been destroyed either maunally or by an error.

The second means you are passing the wrong side signalling data into p.signal() or passing the same data more than once. This is probably a problem with your sendVideoAddress method.

Set p._debug = console.log and post a pastebin with the full browser log of both sides during the issue.

chlamy commented 5 years ago

Thanks for your reply.

This is the reloaded page user : https://pastebin.com/1cqhmW1E

This is the not reloaded page user (with errors) : https://pastebin.com/c94vSRFe

Probably the instance of Peer (p) not be reinstanciate correctly during the recall.

t-mullen commented 5 years ago

You need construct a new peer object for each connection. Peers are one-to-one and one-use. You can't "reuse" peer objects.

You can think of them as the ends of a single connection. When that connection is stopped, the ends are no longer valid.

t-mullen commented 5 years ago

When peer.on('close') fires, you shouldn't use that peer reference for anything further, except maybe to do some cleanup in your application. It's destroyed on close, after a few seconds.

chlamy commented 5 years ago

When I debug my code, p is instanciated 2 times for each call by startPeer function. But it is like p keeps old instance of first peer

t-mullen commented 5 years ago

You're probably getting the new signal before you get the close event and set p to null. A common method of doing signalling is to "tag" each signal message with the peer's ID and keeping track of which peer should receive signals from which peer.

Signalling can be done in a lot of ways though, and it's not in the scope of simple-peer.

There's several libraries that make it simpler, if you don't want to do it yourself: https://github.com/t-mullen/simple-signal (Disclaimer, I'm the author). https://github.com/mafintosh/signalhub

chlamy commented 5 years ago

For send signals, I use real time Laravel Echo.

This is order of exeution code : https://pastebin.com/aFnKS4hp

bharathkumar-chandrasekaran commented 4 years ago

To destroy the peer object can we do peer.destroy() and then peer = new Peer({...}) ??? The reason I'm asking is due to the fact that I get the cannot signal after peer is destroyed error even after I destroy and reinitialize it.

ChrisK1994 commented 3 years ago

To destroy the peer object can we do peer.destroy() and then peer = new Peer({...}) ??? The reason I'm asking is due to the fact that I get the cannot signal after peer is destroyed error even after I destroy and reinitialize it.

I have problem with this now, did you solve it?

maxwhoppa commented 3 years ago

To destroy the peer object can we do peer.destroy() and then peer = new Peer({...}) ??? The reason I'm asking is due to the fact that I get the cannot signal after peer is destroyed error even after I destroy and reinitialize it.

I have problem with this now, did you solve it?

+1 I also have this issue. Did you end up figuring it out?

ChrisK1994 commented 3 years ago

To destroy the peer object can we do peer.destroy() and then peer = new Peer({...}) ??? The reason I'm asking is due to the fact that I get the cannot signal after peer is destroyed error even after I destroy and reinitialize it.

I have problem with this now, did you solve it?

+1 I also have this issue. Did you end up figuring it out?

If I recall correctly this was a problem with socket listeners, I didn't delete old listeners before setting new. socket.current.off("signal"); before socket.current.on("signal", (data) => {} Feel free to use code from my repository, everything there works fine.

maxwhoppa commented 3 years ago

Forgot to leave a reply, the issue was being caused due to me re-declaring a socket function through a separate function calI. The socket functions can only be declared once (obviously. whoops.) I appreciate the help, your repo made me realize my issue.

ChrisK1994 commented 3 years ago

Forgot to leave a reply, the issue was being caused due to me re-declaring a socket function through a separate function calI. The socket functions can only be declared once (obviously. whoops.) I appreciate the help, your repo made me realize my issue.

yeah i told you exactly this in my previous message

erfi-integral commented 2 years ago

Awesome article of erfi