2

When I create a new RTCPeerConnection(), I am unable to destroy it with peer.close(), as far as I can see, and after some time I run out of resources. When a webpage creates lots of RTCPeerConnections, it stops working after about 600 attempts and throws the following error in Chrome:

Uncaught DOMException: Failed to construct 'RTCPeerConnection': Cannot create so many PeerConnections

Here is a test script, which will help you get the error. It is illustrative only, the problem occurs even if the peers are created much slower:

var i = 1;

function peer() {
  var peer = new RTCPeerConnection();
  setTimeout(() => {
    peer.close();
    peer=null;
  }, 10);
  console.log(i++);
}

setInterval(peer, 20);
// run the script and wait on console to see the error

I expect it to release all resources when peer.close() is called, or at least when peer is set to null, so I see no reason why browser throws the error that there is so many PeerConnections. Am I doing anything incorrectly? How do I destroy the peer properly? Thank you

Tomas M
  • 6,919
  • 6
  • 27
  • 33
  • Your interval timer runs about every 16 milliseconds or so, but your timeout to close the connections waits 400 milliseconds. Thus over time you're creating about 25 times more connections than you're closing. Why would you expect any other result than what you're seeing? – Pointy Aug 28 '18 at 12:49
  • Why are you doing this? Are you load testing something? :) – Nisarg Shah Aug 28 '18 at 12:50
  • @Pointy The timeouts make no difference. I've edited the sample code, it fails anyway – Tomas M Aug 28 '18 at 12:51
  • @Nisarg Shah: this is just sample code to illustrate the behavior – Tomas M Aug 28 '18 at 12:52
  • As Mozilla the close is experimental, it might not work, keep track of what number is possible to be opened at once, if you need more, turn to websockets. Also, Mozilla says using Adapter.js might be better. – Akxe Aug 28 '18 at 12:53
  • I can see it works fine in Mozilla. So perhaps a bug in Chrome garbage collector? – Tomas M Aug 28 '18 at 12:55
  • @TomasM It sounds to me like an intentional limit imposed by Chrome developers. There *might* be a command line flag or a preference to control this. – Nisarg Shah Aug 28 '18 at 13:05
  • For me it looked like in chrome as 500 was made then after a while another 500 could have been made. Maybe the garbage collection is delayed. – Exceptional NullPointer Aug 28 '18 at 13:10
  • The spec does say, [A user agent will always use congestion control. This ensures that WebRTC cannot be used to flood the network.](https://www.w3.org/TR/webrtc/#impact-on-local-network) – Nisarg Shah Aug 28 '18 at 13:15
  • Possible duplicate of [How to clear RTCPeerConnection (WebRTC)?](https://stackoverflow.com/questions/49532939/how-to-clear-rtcpeerconnection-webrtc) – Nisarg Shah Aug 28 '18 at 13:18
  • ^ I have linked the duplicate as it refers to the same problem. However the solution doesn't work for me. – Nisarg Shah Aug 28 '18 at 13:20
  • The instances of `RTCPeerConnexion` you created are never opened, so calling the [`close`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/close) method on these objects will do nothing. Have you tried to set higher timeouts (0.2 seconde), maybe chrome can't release the memory with these timeouts. – Chocolord Aug 28 '18 at 13:33
  • @Chocolord: my original application tries to connect once every 60 seconds only, and after about two hours I get the same problem - The issue is NOT in the milliseconds here in my example code. – Tomas M Aug 28 '18 at 18:09
  • Setting to null makes no difference – Tomas M Aug 28 '18 at 18:16
  • try to run my code on snap , it works – Ahmed amin shahin Aug 28 '18 at 19:01
  • its working with me on chrome and firefox as well ... good luck – Ahmed amin shahin Aug 28 '18 at 19:27

2 Answers2

0

Try setting peer to null so it gets garbage collected. See these notes from the person who implemented the limit. If this does not work ask in that mailing list thread

Philipp Hancke
  • 15,855
  • 2
  • 23
  • 31
-1

OK , that was confusing mystery , fortunately it is solved , i will try to give you an example so anyone who read this post can understand what is happening exactly .

assume that you have built your own program , that can count files in a single folder , and you ordered the program to count files on folder C:\Files

that folder path contain 500 files . the program will take maximum 1 hour to read the 500 files , thats his maximum ability , so you give him the order and hit enter .

after one hour , you came back you saw the program is ( Dead ) , you investigate what is the problem ? then you find out that since his maximum ability to read 500 files on hour and the folder having 500 files , its no way he can make error , but the error appeared because there is someone keep throwing files on this folder with like infinity loop , its like it takes him 1 second to read a file and within the same one second there is 5 more files coming on accumulative way he start counting and counting while new files are counted cumulatively .

this is exactly what is happening on your case , chrome browser is closing the peer connection in one second , and within this one second , you are throwing him 3-4 new peer connection , that makes chrome browser after while flag the error on console , because the calculation on the background of console indicates this is infinity and it will display stack error either sooner or later . a part of that you are flooding your browser cache with setting the interval time with these values .

i been tracing this almost three hours and this is the result i end up with . i will edit this post soon and add the solution on how to resolve it .

OK , i just finished adjusting the code , here is what i end up with run snip code and tell me if you see the errors on your chrome console note : you can remove the sip java-script , i used it to trace your error .

hopefully my post help someone in future .

good luck

 <script src="http://sipjs.com/download/sip-0.7.2.min.js"></script>

 <meta http-equiv="Expires" content="0">
 <meta http-equiv="Pragma" content="no-cache">
 <meta http-equiv="Cache-control" content="no-cache">
 <meta http-equiv="Cache" content="no-cache">
 <script>



  var i = 1;

  function peer() {

  var peer = new RTCPeerConnection();
   
  peer.mediaHandler = null;
  peer.onicecandidate = null; 
  peer.onaddstream = null; 

  peer.close(i);

  setTimeout(() => {

  console.log('Ending Call');

  }, 3500);
  console.log(i++);



  }

 setInterval(peer, 500);


  hangUp = () => {
    let { peer} = this.state;
 
    peer.close();

 
    this.setState({
        peer: null,
      
   
    });
};




</script>