Skip to content

Instantly share code, notes, and snippets.

@potch
Created March 19, 2015 05:15
Show Gist options
  • Select an option

  • Save potch/b2e8986a621827b05a0d to your computer and use it in GitHub Desktop.

Select an option

Save potch/b2e8986a621827b05a0d to your computer and use it in GitHub Desktop.
datachannels test
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<script>
var RTCPeerConnection = typeof window !== 'undefined' &&
(window.mozRTCPeerConnection
|| window.RTCPeerConnection
|| window.webkitRTCPeerConnection);
var RTCSessionDescription = typeof window !== 'undefined' &&
(window.mozRTCSessionDescription
|| window.RTCSessionDescription
|| window.webkitRTCSessionDescription);
var RTCIceCandidate = typeof window !== 'undefined' &&
(window.mozRTCIceCandidate
|| window.RTCIceCandidate
|| window.webkitRTCIceCandidate);
</script>
<script>
function DataChannel(opts) {
opts = opts || {};
var initiator = !!opts.initiator;
var negotiationNeeded = true;
var iceComplete = false;
var pcReady = false;
var dcReady = false;
var readyForCandidates = false;
var candidates = [];
var pc = new RTCPeerConnection({
iceServers: [{
url: 'stun:23.21.150.121',
urls: 'stun:23.21.150.121'
}]
}, {});
var dc = null;
pc.ondatachannel = function (event) {
console.log(event);
dc = event.channel;
dc.onopen = function () {
dcReady = true;
tryReady();
};
}
pc.oniceconnectionstatechange = function (event) {
console.log('ice', pc.iceGatheringState, pc.iceConnectionState);
if (pc.iceConnectionState === 'connected' || pc.iceConnectionState === 'completed') {
pcReady = true;
tryReady();
}
};
pc.onsignalingstatechange = function (event) {
console.log('signaling', pc.signalingState);
};
pc.onicecandidate = function(event) {
if (!event) {
return;
}
if (event.candidate) {
api.onsignal({ candidate: event.candidate });
} else {
iceComplete = true;
}
};
if (initiator) {
dc = pc.createDataChannel("test");
dc.onopen = function () {
dcReady = true;
tryReady();
};
pc.onnegotiationneeded = function () {
if (!negotiationNeeded) {
return;
}
negotiationNeeded = false;
pc.createOffer(function(offer) {
speedHack(offer);
pc.setLocalDescription(new RTCSessionDescription(offer), function() {
setTimeout(function () {
api.onsignal(pc.localDescription || offer);
}, 0);
}, error);
}, error);
};
setTimeout(pc.onnegotiationneeded, 0);
}
function signal(data) {
console.log('[signal]', data);
if (data.sdp) {
pc.setRemoteDescription(new RTCSessionDescription(data), function() {
readyForCandidates = true;
// Flush any buffered candidates.
while (candidates.length) {
pc.addIceCandidate(candidates.pop(), noop, error);
}
if (data.type === 'offer') {
pc.createAnswer(function (answer) {
speedHack(answer);
pc.setLocalDescription(answer, noop, error);
setTimeout(function () {
api.onsignal(pc.localDescription || answer);
}, 0);
}, error);
}
}, error);
}
if (data.candidate) {
// I don't know why I need to buffer these, but if I don't Chrome breaks.
if (readyForCandidates) {
pc.addIceCandidate(new RTCIceCandidate(data.candidate), noop, error);
} else {
candidates.push(new RTCIceCandidate(data.candidate));
}
}
}
function tryReady() {
if (pcReady && dcReady) {
ready(dc);
}
}
function noop() {}
var ready, error;
var readyPromise = new Promise(function (resolve, reject) {
ready = resolve;
error = reject;
});
var api = {
pc: pc,
signal: signal,
onsignal: noop,
ready: readyPromise
};
return api;
}
function speedHack (obj) {
var s = obj.sdp.split('b=AS:30')
if (s.length > 1) obj.sdp = s[0] + 'b=AS:1638400' + s[1]
}
</script>
<script>
var peer1 = new DataChannel({initiator: true});
var peer2 = new DataChannel();
peer1.onsignal = peer2.signal;
peer2.onsignal = peer1.signal;
Promise.all([peer1.ready, peer2.ready]).then(function(dcs) {
var dc1 = dcs[0];
var dc2 = dcs[1];
console.log('all ready');
dc1.onmessage = function (e) {
console.log(e);
};
dc2.onmessage = function (e) {
console.log(e);
};
dc1.onerror = console.error.bind(console, 'peer1:');
dc2.onerror = console.error.bind(console, 'peer2:');
dc1.send('hello');
dc2.send('hey');
}).catch(console.error.bind(console));
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment