peerjs icon indicating copy to clipboard operation
peerjs copied to clipboard

call.on("close") not triggered

Open alfonsograziano opened this issue 4 years ago • 34 comments

Hi, i have a p2p connection and when i do call.close(), on("close",...) is triggered only on the peer that calls che close function. How can i trigger both the peers? Thank's!

alfonsograziano avatar Mar 24 '20 16:03 alfonsograziano

I can confirm the report of @lokk3d. I have the same issue.

Description Unexpected behaviour when closing a MedieConnection between two peers.

Steps to reproduce

  1. Establish a MediaConnection between 2 peers
  2. Execute "call.close()" on peer 1.
  3. Listen to "close" and "error" events on peer 2.
  4. Observe which events are triggered on peer 2 after step 2.

Expected Result Peer 2 should receive a "close" event after peer 1 closed the call. An error event should not be fired.

Actual Result Peer 2 received an "error" event: "Error: Connection to <peerId> disconnected."

Is this intentional?

protyze avatar Apr 12 '20 08:04 protyze

So, how do we close the call? MediaConnection.close does never gets fired. Is this a bug? Any workarounds?

cliqer avatar Dec 15 '20 06:12 cliqer

same problem here . Listen to "close" and "error" events on peer 2. nothing happened if peer 1 close call !!

MoradAbdelgaber avatar Dec 23 '20 00:12 MoradAbdelgaber

@MoradAbdelgaber, just send a signal to destroy the peer through WebSocket. No other way around it.

cliqer avatar Dec 23 '20 00:12 cliqer

Same problem here

AlvaroHerrero avatar Jan 11 '21 11:01 AlvaroHerrero

Same here!

albertogcatalan avatar Jan 29 '21 14:01 albertogcatalan

And same here

mactunechy avatar Feb 15 '21 02:02 mactunechy

and same here

xtrars avatar Feb 15 '21 12:02 xtrars

I found a way that worked for me, I'm using peerjs alongside socket.io, so when i kill the call by peer.close(), I then emit an event "close" via socket.io and the other peer will subscribe to that event with socket.on("close",()=>{})

mactunechy avatar Feb 15 '21 12:02 mactunechy

same problem here . Listen to "close" and "error" events on peer 2. nothing happened if peer 1 close call !!

yeah bro me same problem i think its a bug

amanKumar689 avatar Feb 22 '21 09:02 amanKumar689

I am seeing same unexpected behavior where call.on('close', () => {}) is not being called when call is dropped. If it is useful I can provide some kind of Codepen or similar to replicate the issue

sbehrends avatar Feb 24 '21 23:02 sbehrends

Same issue here :)

YoussF avatar Feb 28 '21 17:02 YoussF

I have a workaround solution that I answered in stackoverflow https://stackoverflow.com/questions/64651890/peerjs-close-video-call-not-firing-close-event/66518772#66518772

azlogs avatar Mar 07 '21 15:03 azlogs

same issue...

rkhaslarov avatar Mar 27 '21 09:03 rkhaslarov

I have a workaround solution that I answered in stackoverflow https://stackoverflow.com/questions/64651890/peerjs-close-video-call-not-firing-close-event/66518772#66518772

is there any workaround without websocket?

naonvl avatar Apr 28 '21 02:04 naonvl

I use the public peerjs server. I was able to manually close the peerConnections by getting them from peer.connections. I noticed that the dataConnection close event still fires, so I wait for this and then close all open peerConnections:

function handlePeerDisconnect() {
  // manually close the peer connections
  for (let conns in peer.connections) {
    peer.connections[conns].forEach((conn, index, array) => {
      console.log(`closing ${conn.connectionId} peerConnection (${index + 1}/${array.length})`, conn.peerConnection);
      conn.peerConnection.close();

      // close it using peerjs methods
      if (conn.close)
        conn.close();
    });
  }
}

peer.on('connection', conn => {
    let call = peer.call(peerToCall, localStream);
   
    // peerjs bug prevents this from firing: https://github.com/peers/peerjs/issues/636
    call.on('close', () => {
        console.log("call close event");
        handlePeerDisconnect();
    });
}

    // this one works
    conn.on('close', () => {
        console.log("conn close event");
        handlePeerDisconnect();
    });
});

I also responded here: https://stackoverflow.com/questions/64651890/peerjs-close-video-call-not-firing-close-event/67404616#67404616

chadwallacehart avatar May 05 '21 15:05 chadwallacehart

I use the public peerjs server. I was able to manually close the peerConnections by getting them from peer.connections. I noticed that the dataConnection close event still fires, so I wait for this and then close all open peerConnections:

function handlePeerDisconnect() {
  // manually close the peer connections
  for (let conns in peer.connections) {
    peer.connections[conns].forEach((conn, index, array) => {
      console.log(`closing ${conn.connectionId} peerConnection (${index + 1}/${array.length})`, conn.peerConnection);
      conn.peerConnection.close();

      // close it using peerjs methods
      if (conn.close)
        conn.close();
    });
  }
}

peer.on('connection', conn => {
    let call = peer.call(peerToCall, localStream);
   
    // peerjs bug prevents this from firing: https://github.com/peers/peerjs/issues/636
    call.on('close', () => {
        console.log("call close event");
        handlePeerDisconnect();
    });
}

    // this one works
    conn.on('close', () => {
        console.log("conn close event");
        handlePeerDisconnect();
    });
});

I also responded here: https://stackoverflow.com/questions/64651890/peerjs-close-video-call-not-firing-close-event/67404616#67404616

what is the conn variable here ?? could you help me i am facing the same

wilsonfurtado2000 avatar Jun 30 '21 06:06 wilsonfurtado2000

I use the public peerjs server. I was able to manually close the peerConnections by getting them from peer.connections. I noticed that the dataConnection close event still fires, so I wait for this and then close all open peerConnections:

function handlePeerDisconnect() {
  // manually close the peer connections
  for (let conns in peer.connections) {
    peer.connections[conns].forEach((conn, index, array) => {
      console.log(`closing ${conn.connectionId} peerConnection (${index + 1}/${array.length})`, conn.peerConnection);
      conn.peerConnection.close();

      // close it using peerjs methods
      if (conn.close)
        conn.close();
    });
  }
}

peer.on('connection', conn => {
    let call = peer.call(peerToCall, localStream);
   
    // peerjs bug prevents this from firing: https://github.com/peers/peerjs/issues/636
    call.on('close', () => {
        console.log("call close event");
        handlePeerDisconnect();
    });
}

    // this one works
    conn.on('close', () => {
        console.log("conn close event");
        handlePeerDisconnect();
    });
});

I also responded here: https://stackoverflow.com/questions/64651890/peerjs-close-video-call-not-firing-close-event/67404616#67404616

yeah but where you are getting the peer id from to close the current disconnected peer call?

rodrigomarcell avatar Jul 08 '21 17:07 rodrigomarcell

@wilsonfurtado2000 - when you create a peer with new Peer(someId), the peer object keeps an array of all the connections you make. If I recall correctly, the connections are stored in some kind of generator object. You cann grab each of them individually - that is what the conn variable is in the handlePeerDisconnect function above. I had to do some inspectionn to find these.

@rodrigomarcell - in tht example I am closing every connection associted with the given peer. You should be able to close specific peers by ID with something like the below:

    function manualClose(TARGET_ID) {
        // close the peer connections
        for (let conns in peer.connections) {
            peer.connections[conns].forEach((conn, index, array) => {

                // Manually close the peerConnections b/c peerJs MediaConnect close not called bug: https://github.com/peers/peerjs/issues/636
                if (conn.peer === TARGET_ID) {
                    console.log(`closing ${conn.connectionId} peerConnection (${index + 1}/${array.length})`, conn.peerConnection);
                    conn.peerConnection.close();

                    // close it using peerjs methods
                    if (conn.close) {
                        conn.close();
                    }
                }
            });
        }
    }

chadwallacehart avatar Jul 14 '21 03:07 chadwallacehart

Maybe I confuse this issue. but I face this same problem, and I resolve it.

my project has 2 block script , one is [connect to], one is [listen connect] if in those 2 way you set 'close' event . then it can fired when other side to close event.

when I get this issue, I only write one side 'close' event....

MaxPao avatar Aug 07 '21 20:08 MaxPao

Just encountered this same issue. Any progress on this?

matallui avatar Apr 22 '22 20:04 matallui

Just encountered this same issue. Any progress on this?

I guess the messages above may help you.

rodrigomarcell avatar Apr 22 '22 22:04 rodrigomarcell

I understand there's workarounds for this. But any updates on whether this is going to be fixed? Looks like this issue has been open since 2020.

matallui avatar Apr 25 '22 16:04 matallui

Not sure what the real fix for this will be, but I managed to get this working with this patch.

If you want to give it a try you should be able to install my patched version of peerjs:

npm i matallui/peerjs#fix_mediastream_close

The solution involved creating a RTCDataChannel for each MediaConnection, similar to what is done to the DataConnection. I still would love to figure out a cleaner way of doing that, but at least this is working for now.

matallui avatar Apr 29 '22 21:04 matallui

Not sure what the real fix for this will be, but I managed to get this working with this patch.

If you want to give it a try you should be able to install my patched version of peerjs:

npm i matallui/peerjs#fix_mediastream_close

The solution involved creating a RTCDataChannel for each MediaConnection, similar to what is done to the DataConnection. I still would love to figure out a cleaner way of doing that, but at least this is working for now.

Not sure how this is working, but it seems to be working great. Thank you :)

JoleMile avatar May 02 '22 10:05 JoleMile

Not sure what the real fix for this will be, but I managed to get this working with this patch.

If you want to give it a try you should be able to install my patched version of peerjs:

npm i matallui/peerjs#fix_mediastream_close

The solution involved creating a RTCDataChannel for each MediaConnection, similar to what is done to the DataConnection. I still would love to figure out a cleaner way of doing that, but at least this is working for now.

I was about to make this myself. Why don't you open a pull request for them ? Your solution works great! Thank you!

AllanPinheiroDeLima avatar May 13 '22 23:05 AllanPinheiroDeLima

@AllanPinheiroDeLima I was just trying to make sure this is the correct solution. I assume at some point the remote close() functionality was working, so would like to understand why it stopped working. I was hoping to figure out a better way without having to create that extra channel. But I guess I can open a PR and go from there.

matallui avatar May 17 '22 00:05 matallui

There was on old PR (#860) that might solve this problem without a separate data channel. Please test it! You can get the patched version with npm i peerjs@rc

jonasgloning avatar May 25 '22 12:05 jonasgloning

@jonasgloning just tested this and have a couple of comments:

1- this (kind of) fixes the issue but it's not good enough in my case... it's only disconnecting when we get the ICE disconnect event, which takes a few seconds after I actually stop the MediaConnection on the sharing side. With the extra DataChannel at least we get an instant disconnect as soon as one side calls MediaConnection.close(), which is the behavior I'd expect according to the docs.

2- I'm getting a TS build error now saying the MediaConnection.answer() requires a mandatory stream argument. Not sure at what point things have changed, but this used to be an optional argument and we could still answer calls without sharing a stream back. Any ideas what happened with that?

matallui avatar May 25 '22 18:05 matallui

This commit seems to be where index.d.ts got removed and the interface for MediaConnection.answer() changed.

matallui avatar May 25 '22 20:05 matallui

Thanks for testing, @matallui!

1- this (kind of) fixes the issue but it's not good enough in my case... it's only disconnecting when we get the ICE disconnect event, which takes a few seconds after I actually stop the MediaConnection on the sharing side. With the extra DataChannel at least we get an instant disconnect as soon as one side calls MediaConnection.close(), which is the behavior I'd expect according to the docs.

You’re right, the delay is to large. So this isn’t a complete solution. Unfortunately, I won’t have the time to look into it the next few weeks. But I would merge a PR with your solution, at least in rc for further testing.

2- I'm getting a TS build error now saying the MediaConnection.answer() requires a mandatory stream argument. Not sure at what point things have changed, but this used to be an optional argument and we could still answer calls without sharing a stream back. Any ideas what happened with that?

There were some inconsistencies with the handwritten types, so I switched to autogenerating them in your linked commit. Turns out the types in the source weren’t accurate either. Fixed in https://github.com/peers/peerjs/commit/666dcd9770fe080e00898b9138664e8996bf5162, more type improvements https://github.com/peers/peerjs/commit/2b53de2de9c3ab7d0cc8bfbbc835e054114bbfdb.

jonasgloning avatar May 25 '22 21:05 jonasgloning

@jonasgloning thanks for the prompt response and for fixing 2). I will submit a PR soon with my fixes for 1) so we can test it in RC and we'll go from there.

matallui avatar May 25 '22 22:05 matallui

@jonasgloning PR submitted. Thanks again for all the help!

matallui avatar May 25 '22 22:05 matallui

when i calling video the peer close by self why this happend'

alibawazeer611 avatar Aug 16 '22 14:08 alibawazeer611