| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Data Channel Demo 1</title> |
| <style> |
| button { |
| font: 18px sans-serif; |
| padding: 8px; |
| } |
| textarea { |
| font-family: monospace; |
| margin: 2px; |
| height: 400px; |
| width: 300px; |
| } |
| div#send { |
| float: left; |
| margin-right: 20px; |
| } |
| div#receive { |
| } |
| div#sendreceive { |
| margin: 0 0 20px 0; |
| } |
| h2 { |
| margin: 0 0 10px 0; |
| } |
| </style> |
| </head> |
| <body> |
| <div id="sendreceive"> |
| <div id="send"> |
| <h2>Send data</h2> |
| <textarea id="dataChannelSendId" rows="5" cols="15" disabled="true" |
| placeholder="Press Start, enter some text, then press Send Data."> |
| </textarea> |
| </div> |
| <div id="receive"> |
| <h2>Received Data</h2> |
| <textarea id="dataChannelReceiveId" rows="5" cols="15" disabled="true"> |
| </textarea> |
| </div> |
| </div> |
| <form> |
| <p>Choose SCTP or RTP for transmitting data.</p> |
| <input type="radio" id="useSctp" name="transportbtn" checked/> |
| <label for="useSctp">Use SCTP</label> |
| <input type="radio" id="useRtp" name="transportbtn"/> |
| <label for="useRtp">Use RTP</label> |
| </form> |
| <button id="startButton">Start</button> |
| <button id="sendButton" disabled>Send Data</button> |
| <button id="closeButton" disabled>Stop</button> |
| <!-- Load the polyfill to switch-hit between Chrome and Firefox --> |
| <script src='../../base/adapter.js'></script> |
| <script> |
| var pc1, pc2, sendChannel, receiveChannel, pcConstraint, dataConstraint; |
| var dataChannelSend = document.getElementById("dataChannelSendId"); |
| var dataChannelReceive = document.getElementById("dataChannelReceiveId"); |
| var sctp_select = document.getElementById('useSctp'); |
| var rtp_select = document.getElementById('useRtp'); |
| var startButton = document.querySelector('button#startButton'); |
| var sendButton = document.querySelector('button#sendButton'); |
| var closeButton = document.querySelector('button#closeButton'); |
| startButton.onclick = createConnection; |
| sendButton.onclick = sendData; |
| closeButton.onclick = closeDataChannels; |
| rtp_select.onclick = enableStartButton; |
| sctp_select.onclick = enableStartButton; |
| |
| function enableStartButton() { |
| startButton.disabled = false; |
| } |
| |
| function disableSendButton() { |
| sendButton.disabled = true; |
| } |
| |
| rtp_select.onclick = sctp_select.onclick = function() { |
| dataChannelReceive.value = ''; |
| dataChannelSend.value = ''; |
| disableSendButton(); |
| enableStartButton(); |
| }; |
| |
| function createConnection() { |
| dataChannelSendId.placeholder = ""; |
| var servers = null; |
| pcConstraint = null; |
| dataConstraint = null; |
| if (sctp_select.checked && |
| webrtcDetectedBrowser === 'chrome' && |
| webrtcDetectedVersion >= 31) { |
| // SCTP is supported from Chrome M31. |
| // No need to pass DTLS constraint as it is on by default in Chrome M31. |
| // For SCTP, reliable and ordered is true by default. |
| trace('Using SCTP based Data Channels'); |
| } else { |
| pcConstraint = {optional: [{RtpDataChannels: true}]}; |
| if (!rtp_select.checked) { |
| // Use rtp data channels for chrome versions older than M31. |
| trace('Using RTP based Data Channels,' + |
| 'as you are on an older version than M31.'); |
| alert('Reverting to RTP based data channels,' + |
| 'as you are on an older version than M31.'); |
| rtp_select.checked = true; |
| } |
| } |
| pc1 = new RTCPeerConnection(servers, pcConstraint); |
| trace('Created local peer connection object pc1'); |
| |
| try { |
| // Data Channel api supported from Chrome M25. |
| // You might need to start chrome with --enable-data-channels flag. |
| sendChannel = pc1.createDataChannel("sendDataChannel", dataConstraint); |
| trace('Created send data channel'); |
| } catch (e) { |
| alert('Failed to create data channel. ' + |
| 'You need Chrome M25 or later with --enable-data-channels flag'); |
| trace('Create Data channel failed with exception: ' + e.message); |
| } |
| pc1.onicecandidate = iceCallback1; |
| sendChannel.onopen = onSendChannelStateChange; |
| sendChannel.onclose = onSendChannelStateChange; |
| |
| pc2 = new RTCPeerConnection(servers, pcConstraint); |
| trace('Created remote peer connection object pc2'); |
| |
| pc2.onicecandidate = iceCallback2; |
| pc2.ondatachannel = receiveChannelCallback; |
| |
| pc1.createOffer(gotDescription1); |
| startButton.disabled = true; |
| closeButton.disabled = false; |
| } |
| |
| function sendData() { |
| var data = dataChannelSend.value; |
| sendChannel.send(data); |
| trace('Sent Data: ' + data); |
| } |
| |
| function closeDataChannels() { |
| trace('Closing data Channels'); |
| sendChannel.close(); |
| trace('Closed data channel with label: ' + sendChannel.label); |
| receiveChannel.close(); |
| trace('Closed data channel with label: ' + receiveChannel.label); |
| pc1.close(); |
| pc2.close(); |
| pc1 = null; |
| pc2 = null; |
| trace('Closed peer connections'); |
| startButton.disabled = false; |
| sendButton.disabled = true; |
| closeButton.disabled = true; |
| dataChannelSend.value = ""; |
| dataChannelReceive.value = ""; |
| dataChannelSend.disabled = true; |
| } |
| |
| function gotDescription1(desc) { |
| pc1.setLocalDescription(desc); |
| trace('Offer from pc1 \n' + desc.sdp); |
| pc2.setRemoteDescription(desc); |
| pc2.createAnswer(gotDescription2); |
| } |
| |
| function gotDescription2(desc) { |
| pc2.setLocalDescription(desc); |
| trace('Answer from pc2 \n' + desc.sdp); |
| pc1.setRemoteDescription(desc); |
| } |
| |
| function iceCallback1(event) { |
| trace('local ice callback'); |
| if (event.candidate) { |
| pc2.addIceCandidate(event.candidate); |
| trace('Local ICE candidate: \n' + event.candidate.candidate); |
| } |
| } |
| |
| function iceCallback2(event) { |
| trace('remote ice callback'); |
| if (event.candidate) { |
| pc1.addIceCandidate(event.candidate); |
| trace('Remote ICE candidate: \n ' + event.candidate.candidate); |
| } |
| } |
| |
| function receiveChannelCallback(event) { |
| trace('Receive Channel Callback'); |
| receiveChannel = event.channel; |
| receiveChannel.onmessage = onReceiveMessageCallback; |
| receiveChannel.onopen = onReceiveChannelStateChange; |
| receiveChannel.onclose = onReceiveChannelStateChange; |
| } |
| |
| function onReceiveMessageCallback(event) { |
| trace('Received Message'); |
| dataChannelReceive.value = event.data; |
| } |
| |
| function onSendChannelStateChange() { |
| var readyState = sendChannel.readyState; |
| trace('Send channel state is: ' + readyState); |
| if (readyState == "open") { |
| dataChannelSend.disabled = false; |
| dataChannelSendId.focus(); |
| sendButton.disabled = false; |
| closeButton.disabled = false; |
| } else { |
| dataChannelSend.disabled = true; |
| sendButton.disabled = true; |
| closeButton.disabled = true; |
| } |
| } |
| |
| function onReceiveChannelStateChange() { |
| var readyState = receiveChannel.readyState; |
| trace('Receive channel state is: ' + readyState); |
| } |
| |
| </script> |
| </body> |
| </html> |