Skip to content

Instantly share code, notes, and snippets.

@jure
Created July 2, 2014 20:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jure/1da505b52bc8d1d33675 to your computer and use it in GitHub Desktop.
Save jure/1da505b52bc8d1d33675 to your computer and use it in GitHub Desktop.
Raw WebRTC APIs memory leak/CPU usage spike
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="./overload-webrtc.js"></script>
</head>
<body>
</body>
</html>
(function() {
var RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription;
var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate;
var Client = function(config, signalingChannel) {
var self = this;
this.id = Math.random().toString(32);
this.remoteId = null;
this._pc = new RTCPeerConnection(config);
this._channel = null;
this._signalingChannel = signalingChannel;
this._requests = {};
this._pc.onicecandidate = function(evt) {
if (evt.candidate)
self._signalingChannel.send(self.id, self.remoteId, JSON.stringify({ "candidate": evt.candidate }));
};
this._pc.onnegotiationneeded = function() {
self._pc.createOffer(function(desc) {
self.localDescCreated(desc);
}, function(error) {
console.error("Failed to create offer:", error);
});
};
};
Client.prototype = {
connect: function(remoteId) {
this.remoteId = remoteId;
this._channel = this._pc.createDataChannel(Math.random().toString(32));
this.setupChannel();
},
localDescCreated: function(desc) {
var self = this;
this._pc.setLocalDescription(desc, function() {
self._signalingChannel.send(self.id, self.remoteId, JSON.stringify({ "sdp": self._pc.localDescription }));
}, function(error) {
console.error("Failed to set local description:", error);
});
},
onsignalingmessage: function(remoteId, json) {
var self = this;
if (!this.remoteId) {
this.remoteId = remoteId;
this._pc.ondatachannel = function(evt) {
self._channel = evt.channel;
self.setupChannel();
};
}
var message = JSON.parse(json);
if (message.sdp) {
this._pc.setRemoteDescription(new RTCSessionDescription(message.sdp), function() {
if (self._pc.remoteDescription.type == "offer") {
self._pc.createAnswer(function(desc) {
self.localDescCreated(desc);
}, function(error) {
console.error("Failed to create answer:", error);
});
}
}, function(error) {
console.error("Failed to set remote description:", error);
});
} else {
this._pc.addIceCandidate(new RTCIceCandidate(message.candidate),
function() {}, function(error) {
console.error("Failed to add ice candidate:", error);
});
}
},
setupChannel: function() {
var self = this;
this._channel.onopen = function() {
self.destroy();
console.log('Disconnecting client', self.id);
delete clients[self.id];
};
this._channel.onmessage = function(evt) {
console.log('Message');
var message = JSON.parse(evt.data);
if (message.type === 'request') {
self._channel.send(JSON.stringify({
id: message.id,
type: 'response'
}));
} else {
if (self._requests[message.id]) {
delete self._requests[message.id];
} else {
console.error("Unknown id:", message.id);
}
}
};
},
sendRequest: function() {
var self = this;
this._channel.send(JSON.stringify(request));
},
destroy: function () {
var self = this;
self._pc.close();
self._pc = null;
//self._channel.close();
}
};
var clients = {};
var signalingChannel = {
send: function(from, to, message) {
clients[to].onsignalingmessage(from, message);
}
};
setInterval(function() {
var client1 = new Client({'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }]},
signalingChannel);
clients[client1.id] = client1;
var client2 = new Client({'iceServers': [{ 'url': 'stun:stun.l.google.com:19302' }]},
signalingChannel);
client1.connect(client2.id);
console.log('Connecting client 1 and 2.');
clients[client2.id] = client2;
}, 200);
window.clients = clients;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment