Md Asiful Haque

Full Stack Dev | ASP.Net, Laravel, AngularJs, Flutter

Advanced JS: Prototypal inheritance, WebSockets and WebRTC

Advanced JavaScript techniques and concepts like Prototypal inheritence, websockets and WebRTC can be used to create more complex and powerful web applications. Prototypal inheritance is a way of creating objects in JavaScript that is based on prototyping, rather than classes. WebSockets are a web technology that provides full-duplex communication channels over a single TCP connection. WebRTC is a free, open-source project that enables real-time communication over the web.

Prototypal inheritance

Prototypal inheritance is a way of creating objects in JavaScript that have a prototype relationship with other objects. The prototype is an object that serves as a template for creating new objects. When you create an object in JavaScript, you can specify the object’s prototype. This in turns determines the object’s inherited properties and methods.

Here’s an example of how prototypal inheritance works in JavaScript:

let animal = {
  eats: true
};

let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

console.log(rabbit.eats); // true

In this example, the animal object is the prototype for the rabbit object. The rabbit object inherits the eats property from the animal object, so it has access to the eats property even though it is not directly defined on the rabbit object.

Benefits

One of the main benefits of prototypal inheritance is that it is simple and flexible. In JavaScript, you can create a new object that inherits from an existing object simply by setting the prototype of the new object to be the existing object. This is much simpler than the class-based inheritance model. And it doesn’t requires you to define classes and create objects from those classes.

In a prototype chain, an object can inherit properties and methods from its prototype, and the prototype can inherit properties and methods from its own prototype, and so on. This allows for a hierarchy of objects to be created, with each object in the chain inheriting properties and methods from its ancestors.

The prototype chain is different from the class-based inheritance model used in languages like Java. In a class-based inheritance model, inheritance is achieved through the use of classes, which are templates for creating objects. Objects are created by instantiating a class, and they inherit the properties and methods defined in the class.

There are several other advanced concepts related to prototypal inheritance in JavaScript. One of these is the Object.create() method, which can be used to create an object with a specified prototype. Another advanced concept is the Object.getPrototypeOf() method, which can be used to get the prototype of an object.

Websockets

WebSockets is a technology that allows for bidirectional communication between a client and a server over the web. It is a web technology that provides full-duplex communication channels over a single TCP connection. This means that the client and server can send messages to each other at any time, without the need to poll the server for new data.

WebSockets are often used in real-time applications such as chat applications, multiplayer games, and collaborative software. They are also used in scenarios where low latency is important, such as in financial trading applications.

Here is an example of how to use WebSockets in JavaScript:

const socket = new WebSocket('ws://example.com/ws');

socket.onopen = () => {
  console.log('WebSocket connection opened');
  socket.send('Hello server!');
};

socket.onmessage = (event) => {
  console.log(event.data);
};

socket.onclose = () => {
  console.log('WebSocket connection closed');
};

We created a new WebSocket object and pass it the URL of the server that we want to connect to. We then set up event handlers for the onopen, onmessage, and onclose events. The onopen event is fired when the WebSocket connection is established, the onmessage event is fired when the server sends a message to the client, and the onclose event is fired when the WebSocket connection is closed.

WebSocket events:

In addition to the onopen, onmessage, and onclose events that are shown in the example above, there are several other events that you can handle when working with WebSockets. These include the onerror event, which is fired when an error occurs; the onclose event, which is fired when the WebSocket connection is closed; and the onping and onpong events, which are used for the WebSocket ping/pong mechanism.

WebSocket messages:

WebSockets use a message-based API, which means that messages are sent and received asynchronously. You can send a message over a WebSocket connection by calling the send() method on the WebSocket object, and you can receive a message by handling the onmessage event. WebSocket messages can be text or binary data.

WebSocket protocols:

WebSockets use a subprotocol to define the format of the data that is sent over the WebSocket connection. There are several standard WebSocket subprotocols that are widely used, such as the WebSocket Protocol and the JSON-RPC Protocol. You can specify the subprotocol that you want to use when you create a new WebSocket object.

WebSocket security:

WebSockets use the same security measures as HTTPS, so they are encrypted and secure. However, it is important to ensure that you are using WebSockets securely, as with any network communication. This includes verifying the identity of the server and protecting against attacks such as cross-site scripting (XSS) and cross-site request forgery (CSRF).

WebRTC

WebRTC (Web Real-Time Communication) is a technology that enables real-time communication over the web. It allows for the creation of applications that can share audio, video, and data in real time. WebRTC doesn’t need plug-ins or other third-party software.

WebRTC is a free, open-source project that is supported by most modern web browsers. These includes likes of Google Chrome, Mozilla Firefox, and Apple Safari. It is commonly used to build applications such as video conferencing, live streaming, and peer-to-peer file sharing.

WebRTC uses a set of APIs (Application Programming Interfaces) to enable real-time communication over the web. These APIs include the getUserMedia() API, which allows a web page to access the user’s camera and microphone; the RTCPeerConnection API, which allows for the establishment of a peer-to-peer connection between two devices; and the RTCDataChannel API, which allows for the exchange of data between two devices in real time.

Using WebRTC in JavaScript to build a simple video chat application:

// Get audio and video stream from the user's device
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
  .then((stream) => {
    // Display the video stream in a video element
    const videoElement = document.getElementById('local-video');
    videoElement.srcObject = stream;

    // Create an RTCPeerConnection to establish a peer-to-peer connection
    const peerConnection = new RTCPeerConnection();

    // Add the audio and video streams to the RTCPeerConnection
    stream.getTracks().forEach((track) => {
      peerConnection.addTrack(track, stream);
    });

    // Set up event handlers for the RTCPeerConnection
    peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        // Send the ICE candidate to the other peer
        sendMessage({ type: 'candidate', candidate: event.candidate });
      }
    };

    peerConnection.ontrack = (event) => {
      // Display the video stream from the other peer in a video element
      const videoElement = document.getElementById('remote-video');
      videoElement.srcObject = event.streams[0];
    };

    // Send an offer to the other peer to establish the connection
    peerConnection.createOffer()
      .then((offer) => {
        sendMessage({ type: 'offer', offer: offer });
        peerConnection.setLocalDescription(offer);
      });
  });

// Function to send a message over the WebSocket connection
function sendMessage(message) {
  const jsonMessage = JSON.stringify(message);
  socket.send(jsonMessage);
}

This example uses the getUserMedia() API to get audio and video streams from the user’s device, and displays the video stream in a video element. It then creates an RTCPeerConnection to establish a peer-to-peer connection with another device.

The example sets up event handlers for the RTCPeerConnection, including the onicecandidate event, which is fired when an ICE (Interactive Connectivity Establishment) candidate is available, and the ontrack event, which is fired when a track (such as an audio or video stream) is received from the other peer.

Finally, the example uses the createOffer() method to create an offer to establish the connection with the other peer, and sends the offer over the WebSocket connection using the sendMessage() function.

Detailed Example:

// Set up a WebSocket connection to the server
const socket = new WebSocket('ws://localhost:8080');

// When the WebSocket connection is opened, send a message to the server
socket.onopen = () => {
  socket.send('Hello server!');
};

// When a message is received from the server, handle the message
socket.onmessage = (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'offer':
      // If the message is an offer, receive the offer and create an answer
      const peerConnection = new RTCPeerConnection();
      peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
      peerConnection.createAnswer()
        .then((answer) => {
          peerConnection.setLocalDescription(answer);
          sendMessage({ type: 'answer', answer: answer });
        });
      break;
    case 'answer':
      // If the message is an answer, receive the answer and set the remote description
      peerConnection.setRemoteDescription(new RTCSessionDescription(message.answer));
      break;
    case 'candidate':
      // If the message is an ICE candidate, add the candidate to the peer connection
      peerConnection.addIceCandidate(new RTCIceCandidate(message.candidate));
      break;
  }
};

// Function to send a message over the WebSocket connection
function sendMessage(message) {
  const jsonMessage = JSON.stringify(message);
  socket.send(jsonMessage);
}

// Get audio and video stream from the user's device
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
  .then((stream) => {
    // Display the video stream in a video element
    const videoElement = document.getElementById('local-video');
    videoElement.srcObject = stream;

    // Create an RTCPeerConnection to establish a peer-to-peer connection
    const peerConnection = new RTCPeerConnection();

    // Add the audio and video streams to the RTCPeerConnection
    stream.getTracks().forEach((track) => {
      peerConnection.addTrack(track, stream);
    });

    // Set up event handlers for the RTCPeerConnection
    peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        // Send the ICE candidate to the other peer
        sendMessage({ type: 'candidate', candidate: event.candidate });
      }
    };

    peerConnection.ontrack = (event) => {
      // Display the video stream from the other peer in a video element
      const videoElement = document.getElementById('remote-video');
      videoElement.srcObject = event.streams[0];
    };

    // Send an offer to the other peer to establish the connection
    peerConnection.createOffer()
      .then((offer) => {
        sendMessage({ type: 'offer', offer: offer });
        peerConnection.setLocalDescription(offer);
      });
  });

Explanation

The first part of the code sets up a WebSocket connection to a server at ws://localhost:8080. It sets up an event handler for the onopen event, which is fired when the WebSocket connection is opened, and an event handler for the onmessage event, which is fired when a message is received from the server.

The onmessage event handler parses the message received from the server and checks the type field of the message. If the message is an offer, it creates an RTCPeerConnection and sets the remote description to the offer received from the server. It then creates an answer and sends it back to the server using the sendMessage() function.

If the message is an answer, the event handler sets the remote description of the RTCPeerConnection to the answer received from the server. If the message is an ICE candidate, the event handler adds the candidate to the RTCPeerConnection.

The sendMessage() function is used to send a message over the WebSocket connection. It takes a message object as an argument, stringifies it to JSON, and sends it over the WebSocket connection using the send() method.

The second part of the code gets an audio and video stream from the user’s device using the getUserMedia() API. It displays the video stream in a video element and creates an RTCPeerConnection. It adds the audio and video streams to the RTCPeerConnection and sets up event handlers for the onicecandidate and ontrack events.

Finally, it sends an offer to the server to establish the connection using the createOffer() method.

Moreover,

This code sets up a WebSocket connection to a server at ws://localhost:8080, and sends a message to the server when the WebSocket connection is opened. It then waits for messages from the server, and handles them when they are received.

The code also uses the getUserMedia() API to get audio and video streams from the user’s device, and displays the video stream in a video element. It then creates an RTCPeerConnection to establish a peer-to-peer connection with another device.

The code sets up event handlers for the RTCPeerConnection, including the onicecandidate event, which is fired when an ICE (Interactive Connectivity Establishment) candidate is available, and the ontrack event, which is fired when a track (such as an audio or video stream) is received from the other peer.

Finally, the code uses the createOffer() method to create an offer to establish the connection with the other peer, and sends the offer over the WebSocket connection using the sendMessage() function.

In Summary;

Prototypal inheritance allows for a more flexible and dynamic way of creating objects and organizing code in JavaScript. WebSockets are commonly used in real-time applications where low latency is important. WebRTC is used to build video conferencing and live streaming applications on the web.

You can Also refer to the official MDN docs for more in-depth details of these concepts.

Leave a Comment