Building Real-Time Communication in Angular with WebRTC

Introduction

Real-time communication has become an essential aspect of many web applications. Angular, a popular JavaScript framework, provides a powerful platform for building robust web applications. When combined with WebRTC (Web Real-Time Communication), Angular enables developers to create real-time audio, video, and data-sharing functionalities directly in the browser. In this article, we will explore the concept of WebRTC and its integration with Angular. We will build a simple project that demonstrates the power of WebRTC for real-time communication and provide code snippets and explanations to help you understand the underlying concepts.

What is WebRTC?

WebRTC is an open-source framework that allows real-time communication between web browsers. It provides a set of JavaScript APIs that enable developers to establish peer-to-peer connections for audio, video, and data sharing. WebRTC eliminates the need for plugins or external software, making it a native feature of modern web browsers. It offers secure and efficient communication channels, making it ideal for applications such as video conferencing, file sharing, and real-time collaboration.

Setting Up an Angular Project

To get started, let's set up a new Angular project. Make sure you have Angular CLI installed. Open your terminal and run the following commands.

$ ng new webrtc-app
$ cd webrtc-app

Implementing WebRTC in Angular

In this section, we'll dive into the integration of WebRTC within an Angular application. We'll cover the necessary steps to establish a connection between peers, stream audio and video, and send/receive data.

Firstly we need to install the wrtc npm package. (wrtc - npm (npmjs.com))

npm i wrtc

Establishing a Connection

To establish a WebRTC connection, we need to create the necessary components, configure the connection, and handle the signaling process between peers.

In the app.component.ts file, import the necessary WebRTC APIs.

import { RTCPeerConnection, RTCSessionDescription } from 'wrtc';

Next, let's create a peer connection and set up the signaling process.

const configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
const peerConnection = new RTCPeerConnection(configuration);

// Signaling process
peerConnection.onicecandidate = (event) => {
  if (event.candidate) {
    // Send the candidate to the remote peer
  }
};

// Handle incoming signaling messages from the remote peer
// Set the received SDP description as the remote description
async function handleSignalingMessage(message: any) {
  const offer = new RTCSessionDescription(message);
  await peerConnection.setRemoteDescription(offer);
  // Create an answer and send it to the remote peer
}

Streaming Audio and Video

To stream audio and video using WebRTC, we need to access the user's media devices and transmit the media stream between peers.

In the app.component.ts file, add the following code to access the user's media devices and send the stream to the remote peer.

navigator.mediaDevices.getUserMedia({ audio: true, video: true })
  .then((stream) => {
    // Add the stream to the local video element
    const localVideo = document.getElementById('local-video') as HTMLVideoElement;
    localVideo.srcObject = stream;

    // Add the stream to the peer connection
    stream.getTracks().forEach((track) => peerConnection.addTrack(track, stream));
  })
  .catch((error) => console.error('Error accessing media devices: ', error));

Sending and Receiving Data

WebRTC also provides data channels for sending arbitrary data between peers. Let's set up a data channel and exchange messages.

In the `app.component.ts

file, add the following code to establish a data channel and handle data transmission.

// Create a data channel
const dataChannel = peerConnection.createDataChannel('myDataChannel');

// Set up event listeners for data channel events
dataChannel.onopen = () => {
  console.log('Data channel opened');
};

dataChannel.onmessage = (event) => {
  const message = event.data;
  console.log('Received message:', message);
};

// Send data through the data channel
const sendData = (message: string) => {
  if (dataChannel.readyState === 'open') {
    dataChannel.send(message);
    console.log('Sent message:', message);
  }
};

Building a Real-Time Chat Application

Let's create a real-time chat application to showcase the power of WebRTC and Angular. This application will leverage the concepts learned so far to enable users to communicate in real-time via text messages.

Designing the User Interface

Create a chat component and design the user interface using Angular's components and styling features. Here's an example template for the chat component.

<div class="chat-container">
  <div class="messages" *ngFor="let message of chatMessages">
    {{ message }}
  </div>
  <input type="text" [(ngModel)]="newMessage" (keydown.enter)="sendMessage()" placeholder="Type your message...">
  <button (click)="sendMessage()">Send</button>
</div>

Implementing the Chat Functionality

In the chat component's TypeScript file, add the following code to implement the chat functionality.

import { Component } from '@angular/core';

@Component({
  selector: 'app-chat',
  templateUrl: './chat.component.html',
  styleUrls: ['./chat.component.css']
})
export class ChatComponent {
  chatMessages: string[] = [];
  newMessage: string = '';

  constructor() {
    // Set up the data channel event listeners
    dataChannel.onmessage = (event) => {
      const message = event.data;
      this.chatMessages.push(message);
    };
  }

  sendMessage() {
    const message = this.newMessage.trim();
    if (message) {
      this.chatMessages.push(message);
      sendData(message);
      this.newMessage = '';
    }
  }
}

That's it for now! Remember to further explore the WebRTC API documentation to unlock more advanced features and possibilities for your projects. Happy coding!