Peer connections

The RTCPeerConnection is the central interface in the WebRTC API. It represents the connection between the local and remote peer, and provice all the function and events necessary to establish the connection.

Establishing a peer connection

Applications implementing WebRTC functionality will usually rely heavily on the RTCPeerConnection interface. From the callers side (that is, the peer initiating a connection), the process to establish a connection is usually the following:

  1. Create a new RTCPeerConnection instance with the appropriate ICE configuration.
  2. Create a local SDP description using RTCPeerConnection.createOffer().
  3. Set the local SDP description using RTCPeerConnection.setLocalDescription().
  4. Transfer (using a signalling service) the local SDP description to the remote peer.
  5. Register a listener for icecandidate events on the RTCPeerConnection.
  6. For each icecandidate events, transfer it (using a signalling service) to the remote peer.
  7. Wait for an incoming remote SDP description from the signalling service and set it using RTCPeerConnection.setRemoteDescription().
  8. Wait for incoming remote ICE candidates from the signalling service and add them using RTCPeerConnection.addIceCandidate()

On the callee side, the process is a slightly different.

  1. Create a new RTCPeerConnection instance with the appropriate ICE configuration.
  2. Wait for an incoming remote SDP description from the signalling service and set it using RTCPeerConnection.setRemoteDescription().
  3. Create an answer for the remote SDP description by calling RTCPeerConnection.createAnswer().
  4. Transfer (using a signalling service) the answer to the remote peer.
  5. Register a listener for icecandidate events on the RTCPeerConnection.
  6. For each icecandidate events, transfer it (using a signalling service) to the remote peer.
  7. Wait for incoming remote ICE candidates from the signalling service and add them using RTCPeerConnection.addIceCandidate()

The challenge with this API is that most of these operations are asynchronous, which often make the actual implementation of a WebRTC application complicated. Many of the functions return a Promise which has to be resolved before the next step in the process can continue.

It is recommended that when implementing an application using this API, the developer make use of async and await instead of registering listeners (using Promise.then()), as this makes your code more easy to follow. Consider the following example:

function createAndSendOffer(peerConnection, signallingService) {
    peerConnection.createOffer()
                  .then(offer => {
                      signallingService.send({
                          type: 'offer',
                          data: offer
                      });
                  });
}

When writing the code above using async and await, we get the following:

async function createAndSendOffer(peerConnection, signallingService) {
    const offer = await peerConnection.createOffer();
    signallingService.send({
        type: 'offer',
        data: offer
    });
}