Skip to content

Commit

Permalink
DataChannel support (with fallback)
Browse files Browse the repository at this point in the history
This commit adds support for the WebRTC DataChannel API.
This is -- of course -- preliminary. The interface in the future
should not automatically connect to all peers (neither data channel
or video/audio streams).
  • Loading branch information
jbenet committed Jan 27, 2013
1 parent 3292b5d commit 8c1c6a1
Showing 1 changed file with 119 additions and 2 deletions.
121 changes: 119 additions & 2 deletions lib/webrtc.io.js
Expand Up @@ -56,6 +56,30 @@ var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || nav
rtc.numStreams = 0;
rtc.initializedStreams = 0;


// Reference to the data channels
rtc.dataChannels = {};

// PeerConnection datachannel configuration
rtc.dataChannelConfig = {optional: [ {RtpDataChannels: true} ] };


// check whether data channel is supported.
rtc.checkDataChannelSupport = function() {
try {
// raises exception if createDataChannel is not supported
var pc = new PeerConnection(rtc.SERVER, rtc.dataChannelConfig);
channel = pc.createDataChannel('supportCheck', {reliable: false});
channel.close();
return true;
} catch(e) {
return false;
}
}

rtc.dataChannelSupport = rtc.checkDataChannelSupport();


/**
* Connects to the websocket server.
*/
Expand Down Expand Up @@ -150,7 +174,11 @@ var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || nav
};

rtc.createPeerConnection = function(id) {
var pc = rtc.peerConnections[id] = new PeerConnection(rtc.SERVER);
var config = undefined;
if (rtc.dataChannelSupport)
config = rtc.dataChannelConfig;

var pc = rtc.peerConnections[id] = new PeerConnection(rtc.SERVER, config);
pc.onicecandidate = function(event) {
if (event.candidate) {
rtc._socket.send(JSON.stringify({
Expand All @@ -174,6 +202,14 @@ var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || nav
// TODO: Finalize this API
rtc.fire('add remote stream', event.stream, id);
};

if (rtc.dataChannelSupport) {
pc.ondatachannel = function (evt) {
console.log('data channel connecting ' + id);
rtc.addDataChannel(id, evt.channel);
};
};

return pc;
};

Expand Down Expand Up @@ -261,14 +297,95 @@ var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || nav
}
};


rtc.attachStream = function(stream, domId) {
document.getElementById(domId).src = URL.createObjectURL(stream);
};


rtc.createDataChannel = function(pcOrId, label) {
if (!rtc.dataChannelSupport) {
alert('webRTC data channel is not yet supported in this browser,'
+ ' or you must turn on experimental flags');
return;
}

if (typeof(pcOrId) === 'string') {
id = pcOrId;
pc = rtc.peerConnections[pcOrId];
} else {
pc = pcOrId;
id = undefined;
for (var key in rtc.peerConnections) {
if (rtc.peerConnections[key] === pc)
id = key;
}
}

if (!id)
throw new Error ('attempt to createDataChannel with unknown id');

if (!pc || !(pc instanceof PeerConnection))
throw new Error ('attempt to createDataChannel without peerConnection');

// need a label
label = label || 'fileTransfer' || String(id);

// chrome only supports reliable false atm.
options = {reliable: false};

try {
console.log('createDataChannel ' + id);
channel = pc.createDataChannel(label, options);
} catch (error) {
console.log('seems that DataChannel is NOT actually supported!');
throw error;
}

return rtc.addDataChannel(id, channel);
}

rtc.addDataChannel = function(id, channel) {

channel.onopen = function() {
console.log('data stream open ' + id)
rtc.fire('data stream open', channel);
}

channel.onclose = function(event) {
delete rtc.dataChannels[id];
console.log('data stream close ' + id)
rtc.fire('data stream close', channel);
}

channel.onmessage = function(message) {
console.log('data stream message ' + id);
console.log(message);
rtc.fire('data stream data', channel, message.data);
}

channel.onerror = function(err) {
console.log('data stream error ' + id + ': ' + err);
rtc.fire('data stream error', channel, err);
}

// track dataChannel
rtc.dataChannels[id] = channel;
return channel;
};

rtc.addDataChannels = function() {
if (!rtc.dataChannelSupport)
return;

for (var connection in rtc.peerConnections)
rtc.createDataChannel(connection);
};


rtc.on('ready', function() {
rtc.createPeerConnections();
rtc.addStreams();
rtc.addDataChannels();
rtc.sendOffers();
});

Expand Down

0 comments on commit 8c1c6a1

Please sign in to comment.