UNPKG

webrtc-samples

Version:

Project checking for WebRTC GitHub samples repo

219 lines (186 loc) 6.74 kB
/* * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. */ 'use strict'; var localConnection; var remoteConnection; var sendChannel; var receiveChannel; var pcConstraint; var megsToSend = document.querySelector('input#megsToSend'); var sendButton = document.querySelector('button#sendTheData'); var orderedCheckbox = document.querySelector('input#ordered'); var sendProgress = document.querySelector('progress#sendProgress'); var receiveProgress = document.querySelector('progress#receiveProgress'); var errorMessage = document.querySelector('div#errorMsg'); var receivedSize = 0; var bytesToSend = 0; sendButton.onclick = createConnection; // Prevent data sent to be set to 0. megsToSend.addEventListener('change', function(e) { if (this.value <= 0) { sendButton.disabled = true; errorMessage.innerHTML = '<p>Please enter a number greater than zero.</p>'; } else { errorMessage.innerHTML = ''; sendButton.disabled = false; } }); function createConnection() { sendButton.disabled = true; megsToSend.disabled = true; var servers = null; pcConstraint = null; bytesToSend = Math.round(megsToSend.value) * 1024 * 1024; // Add localConnection to global scope to make it visible // from the browser console. window.localConnection = localConnection = new RTCPeerConnection(servers, pcConstraint); trace('Created local peer connection object localConnection'); var dataChannelParams = {ordered: false}; if (orderedCheckbox.checked) { dataChannelParams.ordered = true; } sendChannel = localConnection.createDataChannel( 'sendDataChannel', dataChannelParams); sendChannel.binaryType = 'arraybuffer'; trace('Created send data channel'); sendChannel.onopen = onSendChannelStateChange; sendChannel.onclose = onSendChannelStateChange; localConnection.onicecandidate = iceCallback1; localConnection.createOffer(gotDescription1, onCreateSessionDescriptionError); // Add remoteConnection to global scope to make it visible // from the browser console. window.remoteConnection = remoteConnection = new RTCPeerConnection(servers, pcConstraint); trace('Created remote peer connection object remoteConnection'); remoteConnection.onicecandidate = iceCallback2; remoteConnection.ondatachannel = receiveChannelCallback; } function onCreateSessionDescriptionError(error) { trace('Failed to create session description: ' + error.toString()); } function randomAsciiString(length) { var result = ''; for (var i = 0; i < length; i++) { // Visible ASCII chars are between 33 and 126. result += String.fromCharCode(33 + Math.random() * 93); } return result; } function sendGeneratedData() { sendProgress.max = bytesToSend; receiveProgress.max = sendProgress.max; sendProgress.value = 0; receiveProgress.value = 0; var chunkSize = 16384; var stringToSendRepeatedly = randomAsciiString(chunkSize); var bufferFullThreshold = 5 * chunkSize; var usePolling = true; if (typeof sendChannel.bufferedAmountLowThreshold === 'number') { trace('Using the bufferedamountlow event for flow control'); usePolling = false; // Reduce the buffer fullness threshold, since we now have more efficient // buffer management. bufferFullThreshold = chunkSize / 2; // This is "overcontrol": our high and low thresholds are the same. sendChannel.bufferedAmountLowThreshold = bufferFullThreshold; } // Listen for one bufferedamountlow event. var listener = function() { sendChannel.removeEventListener('bufferedamountlow', listener); sendAllData(); }; var sendAllData = function() { // Try to queue up a bunch of data and back off when the channel starts to // fill up. We don't setTimeout after each send since this lowers our // throughput quite a bit (setTimeout(fn, 0) can take hundreds of milli- // seconds to execute). while (sendProgress.value < sendProgress.max) { if (sendChannel.bufferedAmount > bufferFullThreshold) { if (usePolling) { setTimeout(sendAllData, 250); } else { sendChannel.addEventListener('bufferedamountlow', listener); } return; } sendProgress.value += chunkSize; sendChannel.send(stringToSendRepeatedly); } }; setTimeout(sendAllData, 0); } 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); localConnection.close(); remoteConnection.close(); localConnection = null; remoteConnection = null; trace('Closed peer connections'); } function gotDescription1(desc) { localConnection.setLocalDescription(desc); trace('Offer from localConnection \n' + desc.sdp); remoteConnection.setRemoteDescription(desc); remoteConnection.createAnswer(gotDescription2, onCreateSessionDescriptionError); } function gotDescription2(desc) { remoteConnection.setLocalDescription(desc); trace('Answer from remoteConnection \n' + desc.sdp); localConnection.setRemoteDescription(desc); } function iceCallback1(event) { trace('local ice callback'); if (event.candidate) { remoteConnection.addIceCandidate(event.candidate, onAddIceCandidateSuccess, onAddIceCandidateError); trace('Local ICE candidate: \n' + event.candidate.candidate); } } function iceCallback2(event) { trace('remote ice callback'); if (event.candidate) { localConnection.addIceCandidate(event.candidate, onAddIceCandidateSuccess, onAddIceCandidateError); trace('Remote ICE candidate: \n ' + event.candidate.candidate); } } function onAddIceCandidateSuccess() { trace('AddIceCandidate success.'); } function onAddIceCandidateError(error) { trace('Failed to add Ice Candidate: ' + error.toString()); } function receiveChannelCallback(event) { trace('Receive Channel Callback'); receiveChannel = event.channel; receiveChannel.binaryType = 'arraybuffer'; receiveChannel.onmessage = onReceiveMessageCallback; receivedSize = 0; } function onReceiveMessageCallback(event) { receivedSize += event.data.length; receiveProgress.value = receivedSize; if (receivedSize === bytesToSend) { closeDataChannels(); sendButton.disabled = false; megsToSend.disabled = false; } } function onSendChannelStateChange() { var readyState = sendChannel.readyState; trace('Send channel state is: ' + readyState); if (readyState === 'open') { sendGeneratedData(); } }