Reliable Internet Communication: Maximizing WebSocket and JavaScript Performance

Reliable Internet Communication: Maximizing WebSocket and JavaScript Performance

The importance of ensuring reliable internet connectivity while coding in JavaScript

WebSockets are useful for building real-time, interactive web applications such as chat, gaming, real-time notifications and more. JavaScript enables the client-side logic that allows web applications to take advantage of WebSockets' real-time capabilities. WebSockets rely on an active internet connection to function properly. If the connection is lost or becomes unstable, the WebSocket connection will be disconnected. This can cause problems for web applications that rely on real-time communication, such as multiplayer games or real-time notifications.

The following blog discusses the best ways to establish and test internet connectivity when coding in Javascript. Quite often we need to check the state of an internet connection to the server before performing an operation, like sending a message or connecting to chat. There are generally three accepted ways to check for a connection at the time of performing operations: via the browser’s navigator, pinging the server, or fetching data from hosts. In the following, we will explore these methods, providing examples of each.

What are WebSockets?

WebSockets are a communication protocol that enables real-time, bidirectional communication between a client and a server over a single, long-lived connection. They are designed to work over the same ports as HTTP and HTTPS (ports 80 and 443, respectively) and to provide a low-latency, low-overhead communication channel that can be used for a variety of applications such as chat, gaming, real-time notifications, and other types of interactive applications.

How does Javascript work with Websockets?

JavaScript provides the WebSocket interface, which allows developers to open a WebSocket connection to a server and send and receive data. The WebSocket interface is part of the HTML5 standard and is supported by most modern web browsers.

Using JavaScript, developers can create a WebSocket client that connects to a WebSocket server, send data to the server, and receive data from the server. The JavaScript WebSocket API includes events for when the WebSocket connection is opened when data is received when an error occurs, and when the WebSocket connection is closed.

Websockets and internet connectivity

WebSockets use a handshake process to establish the connection between the client and server, and once the connection is established, data can be sent in both directions as WebSocket frames. To establish and maintain a WebSocket connection, both the client and server need to have an active internet connection.

WebSockets can be used to test internet connection by establishing a WebSocket connection between the client and the server and measuring the time it takes to complete the connection. More specifically, WebSockets can be used to send a ping packet to the server, and check the response to see if the connection is active or not.

A ping packet is a small message that is sent from one endpoint (client or server) to another endpoint over a WebSocket connection to check the status of the connection. The purpose of the ping packet is to determine if the connection is still active and to ensure that both ends of the connection are still responsive. When the receiving endpoint receives a ping packet, it should respond with a pong packet to confirm that it is still connected. The ping and pong packets are part of the WebSocket protocol and are used to implement a keep-alive mechanism. This round-trip time (RTT) can be used as an indicator of the quality of the internet connection.

Limitations with Websockets

However, relying on Websockets to maintain a connection and to provide a way to test the status of your connection can present a few challenges

The WebSocket protocol does not confirm packet delivery until the timeout expires, which can make it difficult to determine the status of the connection promptly. any indication of packet delivery status, making it harder to determine if a connection is working properly. Furthermore, the timeout value for WebSockets can be significant, especially for high-speed communications. This can lead to longer wait times for confirmation of a connection.

Also, WebSockets are a bidirectional protocol, which means that it requires a server and a client, so the test would require both sides to be available and properly configured.

Another issue with relying on WebSockets is that it’s not uncommon for unexpected changes in mobile communication networks. When IP, NAT, or network changes occur in a mobile communication network, it can cause issues for WebSockets.

  • IP changes can cause WebSockets to become disconnected, as the client will no longer be able to reach the server using the previous IP address.

  • NAT changes can affect the ability of the client and server to communicate with each other since NAT is responsible for mapping internal IP addresses to external IP addresses. If the NAT mapping changes, the WebSocket connection may be broken.

  • Network changes can cause disruptions to the WebSocket connection, as the client and server may be on different networks or subnets, and may not be able to reach each other.

In addition to these issues, the combination of IP, NAT, and network changes can make it difficult to maintain a consistent WebSocket connection in mobile communication networks, which may impact the reliability of the internet connection test.

Lastly, Some browsers have a tab freezing or sleeping feature to reduce computer resource usage for inactive tabs. This can cause WebSocket connections to close and may result in an unsatisfying user experience.

For all these reasons it becomes essential to establish effective means to test the status of internet connectivity before performing operations. Let's consider some of the options.

Using the browser’s navigator to test the internet connection

Browsers have basic functionality for checking online status. For example, ‘navigator.onLine’ is a property of the Navigator interface in JavaScript that indicates whether the browser is currently online or offline. It returns a boolean value, ‘true’ if the browser is online and ‘false’ if it is offline.

The navigator.onLine property can be used to detect the online/offline status of a browser, which can be useful for web applications that need to function offline or in low-connectivity environments. For example, an application might use this property to determine whether it should display a "You are offline" message, or disable certain features that require an internet connection.

To use navigator.onLine to check internet status, we need to subscribe to events "offline" and "online". By subscribing to these events, we can perform all needed or required actions.

Let's make a code example to describe how to get information about navigate.Online status. The example below shows information about changes in navigate.Online in the console.

window.addEventListener("offline", (event) => {
  console.log("OFFline");
  //other needed or  required actions
  // ...
});
window.addEventListener("online", (event) => {
  console.log("Online");
  //other needed or  required actions
  // ...
});

Limitations with navigator.onLine

However, there are several limitations with using navigator.onLine to determine the internet connection status:

  • It is based on the browser's heuristics and not an actual connection test. The browser may have cached data or have a service worker running, making it appear as if the browser is online even if the device is not connected to a network.

  • It can be affected by various factors such as network configuration or browser extensions, which can lead to inconsistent results.

  • It only checks the status of the browser's connection, not the device's connection. A device may be connected to a network, but the browser may not be able to access the internet due to a proxy or firewall.

  • navigator.onLine only indicates if the browser is currently online or offline and does not provide any information about the type of connection, the quality of the connection, or the reason for the disconnection.

  • It's not supported by all browsers.

For these reasons, it's generally recommended to use a more reliable method of checking internet connection status such as making an actual request to a server and checking the response.

To order to test the online status of the browser, you might develop special features for checking using fetch API.

Using the Fetch API to test the internet connection

The Fetch API is a modern Javascript API for making network requests. It is a way for a website or web application to request information from a server and receive a response. It is built into web browsers and allows a developer to make an HTTP request to a server and get a response back.

The Fetch API can be used to check for an internet connection. A common method is to try and load the website's favicon.ico file, which is typically located in the root directory. By using the fetch method to load it, we can check the HTTP response code. If the code is between 200 and 299, it is a success and we can say that there is an internet connection. If the code is outside of that range, it means there is no internet connection. We can then return a boolean value indicating whether or not there is an internet connection.

Look at the code example below.

This code illustrates actions from the previous paragraph. Every five seconds we request a server for getting favicon.ico file and if we have a response with code 200, it means we are online.

const haveConnection = async () => {
  try {
    const fetchResult = await fetch("/favicon.ico");
    return fetchResult.status  < 300 && fetchResult.status >= 200; 
  } catch (err) {
    return false; // false means no connection
  }
};

setInterval(async () => {
  const result = await haveConnection();
  const statusConnection = result ? "Online" : "OFFline";
  console.log(statusConnection);
}, 5000);

If we have no access to the root of our host, we cannot fetch external host resources, which means we are offline.

Let's make the previous code example a little more efficient. Let's add the current date/time in the URL. This action needs us to avoid using the browser's cache.

const haveConnection = async () => {
  var haveInternet = false;
  try {
const url = 'https://quickblox.com/favicon.ico?d='+Date.now();
      fetch(url, {mode: 'no-cors'})
      .then((response) => {          
          haveInternet = true;
       })       
       .catch((e) => {
          haveInternet = false;          
       })    
         return haveInternet; 
  } 
    catch (err) {
       return false; 
 }
};

Check the internet connection using the ping method

The QuickBlox JavaScript SDK offers a comprehensive toolkit for adding real-time communication features to any website or website application. This includes video conferencing, instant messaging and peer-to-peer video chat.

When building chat apps using QuickBlox JS SDK you could check the internet connection before executing important operations by using the ping method.

In JavaScript, the "ping" method typically refers to a technique used to check if a website or web page is available. It's commonly done by creating an XMLHttpRequest object and sending a GET request to the server and waiting for a response, or by using the Fetch API.

The ping method in the QuickBlox JS SDK already has all described steps. So, by calling the ping method in the QuickBlox JS SDK we have solved two tasks: 1) to check if the client application has an internet connection; 2) to check if the api server application is available. It ensures the stability of the client-server application.

You can check the online status of the host.

try {
  QB.chat.ping(function (error) {
    if (error) {
      // no pong received
    } else {
      // pong received from the server
    }
  });
} catch (e) {
  if (e.name === 'ChatNotConnectedError') {
    // not connected to chat
  }
}

Inside the ping method, a call to the chat host resource is used. Therefore, this method allows you to solve the issue of checking the connection.

Conclusion

Websockets were designed to be implemented in web browsers and servers, and are supported by JavaScript, making them a natural fit for web development. This technology allows for low latency and efficient communication, making it an ideal solution for applications that require real-time updates and interactions. To ensure a smooth operation of WebSockets a stable internet connection is vital.

In this article, we looked at several methods for checking for an internet connection when coding in JavaScript, notably methods based on using the browser’s navigator or the fetch API (local and external resources). By far, the latter is far more reliable.

However, if you choose to build an application using the QuickBlox JavaScript SDK, you can use their effective ping method.

Join the QuickBlox Dev Discord Community ! Share ideas, learn about software, and get support.