| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- (function() {
- // Define "global" variables
-
- var connectButton = null;
- var disconnectButton = null;
- var sendButton = null;
- var messageInputBox = null;
- var receiveBox = null;
-
- var localConnection = null; // RTCPeerConnection for our "local" connection
- var remoteConnection = null; // RTCPeerConnection for the "remote"
-
- var sendChannel = null; // RTCDataChannel for the local (sender)
- var receiveChannel = null; // RTCDataChannel for the remote (receiver)
-
- // Functions
-
- // Set things up, connect event listeners, etc.
-
- function startup() {
- connectButton = document.getElementById('connectButton');
- disconnectButton = document.getElementById('disconnectButton');
- sendButton = document.getElementById('sendButton');
- messageInputBox = document.getElementById('message');
- receiveBox = document.getElementById('receivebox');
-
- // Set event listeners for user interface widgets
-
- connectButton.addEventListener('click', connectPeers, false);
- disconnectButton.addEventListener('click', disconnectPeers, false);
- sendButton.addEventListener('click', sendMessage, false);
- }
-
- // Connect the two peers. Normally you look for and connect to a remote
- // machine here, but we're just connecting two local objects, so we can
- // bypass that step.
-
- function connectPeers() {
- // Create the local connection and its event listeners
-
- localConnection = new RTCPeerConnection();
-
- // Create the data channel and establish its event listeners
- sendChannel = localConnection.createDataChannel("sendChannel");
- sendChannel.onopen = handleSendChannelStatusChange;
- sendChannel.onclose = handleSendChannelStatusChange;
-
- // Create the remote connection and its event listeners
-
- remoteConnection = new RTCPeerConnection();
- remoteConnection.ondatachannel = receiveChannelCallback;
-
- // Set up the ICE candidates for the two peers
-
- localConnection.onicecandidate = e => !e.candidate
- || remoteConnection.addIceCandidate(e.candidate)
- .catch(handleAddCandidateError);
-
- remoteConnection.onicecandidate = e => !e.candidate
- || localConnection.addIceCandidate(e.candidate)
- .catch(handleAddCandidateError);
-
- // Now create an offer to connect; this starts the process
-
- localConnection.createOffer()
- .then(offer => localConnection.setLocalDescription(offer))
- .then(() => remoteConnection.setRemoteDescription(localConnection.localDescription))
- .then(() => remoteConnection.createAnswer())
- .then(answer => remoteConnection.setLocalDescription(answer))
- .then(() => localConnection.setRemoteDescription(remoteConnection.localDescription))
- .catch(handleCreateDescriptionError);
- }
-
- // Handle errors attempting to create a description;
- // this can happen both when creating an offer and when
- // creating an answer. In this simple example, we handle
- // both the same way.
-
- function handleCreateDescriptionError(error) {
- console.log("Unable to create an offer: " + error.toString());
- }
-
- // Handle successful addition of the ICE candidate
- // on the "local" end of the connection.
-
- function handleLocalAddCandidateSuccess() {
- connectButton.disabled = true;
- }
-
- // Handle successful addition of the ICE candidate
- // on the "remote" end of the connection.
-
- function handleRemoteAddCandidateSuccess() {
- disconnectButton.disabled = false;
- }
-
- // Handle an error that occurs during addition of ICE candidate.
-
- function handleAddCandidateError() {
- console.log("Oh noes! addICECandidate failed!");
- }
-
- // Handles clicks on the "Send" button by transmitting
- // a message to the remote peer.
-
- function sendMessage() {
- var message = messageInputBox.value;
- sendChannel.send(message);
-
- // Clear the input box and re-focus it, so that we're
- // ready for the next message.
-
- messageInputBox.value = "";
- messageInputBox.focus();
- }
-
- // Handle status changes on the local end of the data
- // channel; this is the end doing the sending of data
- // in this example.
-
- function handleSendChannelStatusChange(event) {
- if (sendChannel) {
- var state = sendChannel.readyState;
-
- if (state === "open") {
- messageInputBox.disabled = false;
- messageInputBox.focus();
- sendButton.disabled = false;
- disconnectButton.disabled = false;
- connectButton.disabled = true;
- } else {
- messageInputBox.disabled = true;
- sendButton.disabled = true;
- connectButton.disabled = false;
- disconnectButton.disabled = true;
- }
- }
- }
-
- // Called when the connection opens and the data
- // channel is ready to be connected to the remote.
-
- function receiveChannelCallback(event) {
- receiveChannel = event.channel;
- receiveChannel.onmessage = handleReceiveMessage;
- receiveChannel.onopen = handleReceiveChannelStatusChange;
- receiveChannel.onclose = handleReceiveChannelStatusChange;
- }
-
- // Handle onmessage events for the receiving channel.
- // These are the data messages sent by the sending channel.
-
- function handleReceiveMessage(event) {
- var el = document.createElement("p");
- var txtNode = document.createTextNode(event.data);
-
- el.appendChild(txtNode);
- receiveBox.appendChild(el);
- }
-
- // Handle status changes on the receiver's channel.
-
- function handleReceiveChannelStatusChange(event) {
- if (receiveChannel) {
- console.log("Receive channel's status has changed to " +
- receiveChannel.readyState);
- }
-
- // Here you would do stuff that needs to be done
- // when the channel's status changes.
- }
-
- // Close the connection, including data channels if they're open.
- // Also update the UI to reflect the disconnected status.
-
- function disconnectPeers() {
-
- // Close the RTCDataChannels if they're open.
-
- sendChannel.close();
- receiveChannel.close();
-
- // Close the RTCPeerConnections
-
- localConnection.close();
- remoteConnection.close();
-
- sendChannel = null;
- receiveChannel = null;
- localConnection = null;
- remoteConnection = null;
-
- // Update user interface elements
-
- connectButton.disabled = false;
- disconnectButton.disabled = true;
- sendButton.disabled = true;
-
- messageInputBox.value = "";
- messageInputBox.disabled = true;
- }
-
- // Set up an event listener which will run the startup
- // function once the page is done loading.
-
- window.addEventListener('load', startup, false);
- })();
|