Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTCPeerConnection object not clearing after participant leaves #81

Open
magestican opened this issue Aug 31, 2016 · 9 comments
Open

RTCPeerConnection object not clearing after participant leaves #81

magestican opened this issue Aug 31, 2016 · 9 comments

Comments

@magestican
Copy link
Contributor

We are having an issue where in a call with participants A and B, if participant B refreshes / leaves by calling quickconnect.close() the RTCPeerConnection object on participant's A chrome remains alive. (variable is not being picked up by garbage collector or .close() is not being executed on it)

Looking deep into rtc-quickconnect source quickconnect.close() will use rtc-tools to clean the RTCPeerConnection only on the participant executing the quickconnect.close function, not the other ones.

Is this correct? If so, is there any api we could use to close peer connections upon leaving?
Something like :
quikconnect.on('participant:left',function(rtcPeerConnectionInstance){
rtcPeerConnectionInstance.close();
})

@briely
Copy link
Contributor

briely commented Sep 1, 2016

There is behaviour that is intended to handle a graceful call exit here:

https://github.com/rtc-io/rtc-quickconnect/blob/master/index.js#L916

And and from the party that is leaving:

https://github.com/rtc-io/rtc-quickconnect/blob/master/index.js#L589
https://github.com/rtc-io/rtc-signaller/blob/master/index.js#L231

Similar to your suggestion, the leaving party sends a /leave message which should be received by the message:leave handler on the remote end. Which should result in calls.end, which should clean up the connection via rtc-tools:

https://github.com/rtc-io/rtc-quickconnect/blob/master/lib/calls.js#L110
https://github.com/rtc-io/rtc-quickconnect/blob/master/lib/calls.js#L157

In the case of an ungraceful exit, in the worst case the connection should be cleaned up by the heartbeat failing, unless it has been disabled.

https://github.com/rtc-io/rtc-quickconnect/blob/master/lib/calls.js#L194
https://github.com/rtc-io/rtc-quickconnect/blob/master/lib/heartbeat.js#L29

The current rtc-switchboard may generate a leave message when a peer disconnects, I'm not exactly sure atm.

Do you see the /leave message when .close() is called? Do you see the heartbeat failing if the remote peer just disappears?

@betimer
Copy link
Contributor

betimer commented Sep 2, 2016

@briely
We use rtc-signaller-socket-io. The line below never gets triggered:
https://github.com/rtc-io/rtc-signaller/blob/master/index.js#L231

@briely
Copy link
Contributor

briely commented Sep 2, 2016

That makes sense. Perhaps the /leave behaviour should be moved into rtc-signal.

@warrenjmcdonald
Copy link

@nathanoehlman we have investigated this quite thoroughly today to see what is causing the difference in behaviour in latest quickconnect and rtc-tools, to the older quickconnect and rtc-tools we have been using until recently.

We have eliminated PC signallingState and iceConnectionState
We feel that we have reproduced the correct clean up sequence.
We have tried manually removing the associated mediastreams

In the end we still have no idea what is causing the PC to not be properly cleaned up.

We have double checked the older quickconnect behaviour in the same browser version and it is cleaning up such that the PC objects are properly removed.

We are not sure where to look next but assume there is some reference to the object still in place which is preventing the cleanup such as an event handler etc.

@magestican
Copy link
Contributor Author

@warrenjmcdonald @nathanoehlman
I managed to reproduce this using the latest quickconnect version with the latest rtc-switchboard code.
Just did on console :

  1. node server => on rtc-switchboard //no changes here, localhost:3000

  2. live-server (http web server) => on quickconnect/examples /bundle-demo.html

  3. Added this code to the bundle-demo.html javascript
    https://github.com/rtc-io/rtc-quickconnect#example-usage-using-captured-media

Having two tabs open, upon refresh of client A, checking chrome://webrtc-internals/ there is always an RTCPeerConnection object hanging on client B belonging to client A.

This does not happen in much older versions of quickconnect which we use on production, I can see there how the peer connections get cleared.

@silviapfeiffer
Copy link
Member

Just confirming: you've disabled the heartbeat behaviour?

@nathanoehlman
Copy link
Contributor

@magestican Just trying to replicate your example to reconstruct the behaviour you are seeing with chrome://webrtc-internals/. The behaviour you describe is as I would expect - webrtc-internals seems to display information about PeerConnections that were created in a browser instance up until the point of the instance being refreshed. As case in point is executing the following code, which is the simplest form of creating a connection, closing it, and removing it's references to make it garbage collectable:

var pc = new webkitRTCPeerConnection({ iceServers: []});
pc.close();
pc = undefined;

webrtc-internals will continue to show the details for this peer connection up until the peer connection is closed/refreshed.

Are you saying that this behaviour does not occur with older versions of quickconnect? If so, I have no idea how that'd be occurring. Looking for issues against Chrome shows https://bugs.chromium.org/p/chromium/issues/detail?id=356605, which seems to indicate that PeerConnections used to not be garbage collected due to being tied to the window object, but that should have been fixed a while ago. The bug itself seems to indicate that the webrtc-internals behaviour is as expected, but again, not sure how well it ties in.

@nathanoehlman
Copy link
Contributor

@magestican @warrenjmcdonald @betimer Yep, using the rtc-signaller-socket.io isn't currently sending the /leave message that rtc-signaller does. As per the suggestion from @briely, I'll update rtc-signal/signaller to do this instead, then update rtc-signaller and rtc-signaller-socket.io to use this as the leave behaviour for both.

@nathanoehlman
Copy link
Contributor

The other thing I should mention is that quickconnect does have an additional failsafe mechanism for removing peer connections that are no longer in operation.

Say for instance a peer has closed (due to a browser close, or unexpected disconnect). Each quickconnect peer connection is created with a monitor (https://github.com/rtc-io/rtc-tools/blob/master/monitor.js) that tracks the signaling and ICE connection state change events to ensure that a connection is still valid. In the event of a connection between two peers (A + B) where B is closed unexpectedly, the following should occur:

  1. A will continue to believe the PeerConnection is open.
  2. After a while, the browser will detect that the PeerConnection to B has failed, and the iceConnectionState on the connection held by A will transition to either failed, or closed.
  3. The monitor will pick this up, and emit a closed event.
  4. The closed event causes the logic at https://github.com/rtc-io/rtc-quickconnect/blob/master/index.js#L288 to be execute, causing the cleanup of the connection that A held.

With the ignoreDisconnect property set to true, this failsafe logic still seems to work correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants