How to build a real time with Node and React using WebSocket

How to build a real time with Node and React using WebSocket

WebSockets can be very beneficial for building realtime communication or data streaming applications on the web, such as chat apps and applications that stream images or other types of media. In this tutorial we are going to build a real time with Node and React using WebSockets

WebSockets can be very beneficial for building realtime communication or data streaming applications on the web, such as chat apps and applications that stream images or other types of media. In this tutorial we are going to build a real time with Node and React using WebSockets

The web has traveled a long way to support full-duplex (or two-way) communication between a client and server. This is the prime intention of the **WebSocket **protocol: to provide persistent real-time communication between the client and the server over a single TCP socket connection.

The **WebSocket **protocol has only two agendas : 1) to open up a handshake, and 2) to help the data transfer. Once the server and client both have their handshakes in, they can send data to each other with less overhead at will.

**WebSocket **communication takes place over a single TCP socket using either WS (port 80) or WSS (port 443) protocol. Almost every browser except Opera Mini provides admirable support for **WebSockets **at the time of writing, as per Can I Use. The source code for this application this repo on GitHub.

The story so far

Historically, creating web apps that needed real-time data (like gaming or chat apps) required an abuse of HTTP protocol to establish bidirectional data transfer. There were multiple methods used to achieve real-time capabilities, but none of them were as efficient as WebSockets. HTTP polling, HTTP streaming, Comet, SSE — they all had their own drawbacks.

HTTP polling

The very first attempt to solve the problem was by polling the server at regular intervals. The HTTP long polling lifecycle is as follows:

  1. The client sends out a request and keeps waiting for a response.
  2. The server defers its response until there’s a change, update, or timeout. The request stayed “hanging” until the server had something to return to the client.
  3. When there’s some change or update on the server end, it sends a response back to the client.
  4. The client sends a new long poll request to listen to the next set of changes.

There were a lot of loopholes in long polling — header overhead, latency, timeouts, caching, and so on.

HTTP streaming

This mechanism saved the pain of network latency because the initial request is kept open indefinitely. The request is never terminated, even after the server pushes the data. The first three lifecycle methods of HTTP streaming are the same in HTTP polling.

When the response is sent back to the client, however, the request is never terminated; the server keeps the connection open and sends new updates whenever there’s a change.

Server-sent events (SSE)

With SSE, the server pushes data to the client. A chat or gaming application cannot completely rely on SSE. The perfect use case for SSE would be, e.g., the Facebook News Feed: whenever new posts comes in, the server pushes them to the timeline. SSE is sent over traditional HTTP and has restrictions on the number of open connections.

These methods were not just inefficient, the code that went into them also made developers tired.

Why WebSocket is the prince that was promised

**WebSockets **are designed to supersede the existing bidirectional communication technologies. The existing methods described above are neither reliable nor efficient when it comes to full-duplex real-time communications.

**WebSockets **are similar to SSE but also triumph in taking messages back from the client to the server. Connection restrictions are no longer an issue since data is served over a single TCP socket connection.

Practical tutorial

As mentioned in the introduction, the WebSocket protocol has only two agendas. Let’s see how WebSockets fulfills those agendas. To do that, I’m going to spin off a Node.js server and connect it to a client built with React.js.

Agenda 1: WebSocket establishes a handshake between server and client

Creating a handshake at the server level

We can make use of a single port to spin off the HTTP server and the WebSocket server. The gist below shows the creation of a simple HTTP server. Once it is created, we tie the WebSocket server to the HTTP port:

const webSocketsServerPort = 8000;
const webSocketServer = require('websocket').server;
const http = require('http');
// Spinning the http server and the websocket server.
const server = http.createServer();
server.listen(webSocketsServerPort);
const wsServer = new webSocketServer({
httpServer: server
});

Once the WebSocket server is created, we need to accept the handshake on receiving the request from the client. I maintain all the connected clients as an object in my code with a unique user-id on receiving their request from the browser.

// I'm maintaining all active connections in this object
const clients = {};

// This code generates unique userid for everyuser.
const getUniqueID = () => {
  const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
  return s4() + s4() + '-' + s4();
};

wsServer.on('request', function(request) {
  var userID = getUniqueID();
  console.log((new Date()) + ' Recieved a new connection from origin ' + request.origin + '.');
  // You can rewrite this part of the code to accept only the requests from allowed origin
  const connection = request.accept(null, request.origin);
  clients[userID] = connection;
  console.log('connected: ' + userID + ' in ' + Object.getOwnPropertyNames(clients))
});

So, what happens when the connection is accepted?

While sending the regular HTTP request to establish a connection, in the request headers, the client sends <em>Sec-WebSocket-Key</em>. The server encodes and hashes this value and adds a predefined GUID. It echoes the generated value in the <em>Sec-WebSocket-Accept</em> in the server-sent handshake.

Once the request is accepted in the server (after necessary validations in production), the handshake is fulfilled with status code 101. If you see anything other than status code 101 in the browser, the WebSocket upgrade has failed, and the normal HTTP semantics will be followed.

The <em>Sec-WebSocket-Accept</em> header field indicates whether the server is willing to accept the connection or not. Also, if the response lacks an <em>Upgrade</em> header field, or the <em>Upgrade</em> does not equal websocket, it means the WebSocket connection has failed.

The successful server handshake looks like this:

HTTP GET ws://127.0.0.1:8000/ 101 Switching Protocols
Connection: Upgrade
Sec-WebSocket-Accept: Nn/XHq0wK1oO5RTtriEWwR4F7Zw=
Upgrade: websocket

Creating a handshake at the client level

At the client level, I’m using the same WebSocket package we are using in the server to establish the connection with the server (the WebSocket API in Web IDL is being standardized by the W3C). As soon as the request is accepted by the server, we will see WebSocket Client Connected on the browser console.

Here’s the initial scaffold to create the connection to the server:

import React, { Component } from 'react';
import { w3cwebsocket as W3CWebSocket } from "websocket";

const client = new W3CWebSocket('ws://127.0.0.1:8000');

class App extends Component {
  componentWillMount() {
    client.onopen = () => {
      console.log('WebSocket Client Connected');
    };
    client.onmessage = (message) => {
      console.log(message);
    };
  }
  
  render() {
    return (
      <div>
        Practical Intro To WebSockets.
      </div>
    );
  }
}

export default App;

The following headers are sent by the client to establish the handshake:

HTTP GET ws://127.0.0.1:8000/ 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: vISxbQhM64Vzcr/CD7WHnw==
Origin: http://localhost:3000
Sec-WebSocket-Version: 13

Now that the client and server are connected with mutual handshakes, the WebSocket connection can transmit messages as it receives them, thereby fulfilling the second agenda of WebSocket protocol.

Agenda 2: Real-time message transmission

Real-time streaming of content modification.

I’m going to code a basic real-time document editor where users can join together and edit a document. I’m tracking two events:

  1. User activities: Every time a user joins or leaves, I broadcast the message to all the other connected clients.
  2. Content changes: Every time content in the editor is changed, it is broadcast to all the other connected clients.

The protocol allows us to send and receive messages as binary data or UTF-8 (N.B., transmitting and converting UTF-8 has less overhead).

Understanding and implementing WebSockets is very easy as long as we have a good understanding of the socket events: onopen, onclose, and onmessage. The terminologies are the same on both the client and the server side.

Sending and listening to messages on the client side

From the client, when a new user joins in or when content changes, we trigger a message to the server using client.send to take the new information to the server.

/* When a user joins, I notify the
server that a new user has joined to edit the document. */
logInUser = () => {
  const username = this.username.value;
  if (username.trim()) {
    const data = {
      username
    };
    this.setState({
      ...data
    }, () => {
      client.send(JSON.stringify({
        ...data,
        type: "userevent"
      }));
    });
  }
}

/* When content changes, we send the
current content of the editor to the server. */
onEditorStateChange = (text) => {
 client.send(JSON.stringify({
   type: "contentchange",
   username: this.state.username,
   content: text
 }));
};

The events we track: a user joining and content changing.

And listening to messages from the server are pretty simple:

componentWillMount() {
  client.onopen = () => {
   console.log('WebSocket Client Connected');
  };
  client.onmessage = (message) => {
    const dataFromServer = JSON.parse(message.data);
    const stateToChange = {};
    if (dataFromServer.type === "userevent") {
      stateToChange.currentUsers = Object.values(dataFromServer.data.users);
    } else if (dataFromServer.type === "contentchange") {
      stateToChange.text = dataFromServer.data.editorContent || contentDefaultMessage;
    }
    stateToChange.userActivity = dataFromServer.data.userActivity;
    this.setState({
      ...stateToChange
    });
  };
}

Sending and listening to messages on the server side

In the server, we simply have to catch the incoming message and broadcast it to all the clients connected to the WebSocket. And this is one of the differences between the infamous Socket.IO and WebSocket: we need to manually send the message to all clients when we use WebSockets. Socket.IO is a full-fledged library, so it handles that on its own.

const sendMessage = (json) => {
  // We are sending the current data to all connected clients
  Object.keys(clients).map((client) => {
    clients[client].sendUTF(json);
  });
}

connection.on('message', function(message) {
    if (message.type === 'utf8') {
      const dataFromClient = JSON.parse(message.utf8Data);
      const json = { type: dataFromClient.type };
      if (dataFromClient.type === typesDef.USER_EVENT) {
        users[userID] = dataFromClient;
        userActivity.push(`${dataFromClient.username} joined to edit the document`);
        json.data = { users, userActivity };
      } else if (dataFromClient.type === typesDef.CONTENT_CHANGE) {
        editorContent = dataFromClient.content;
        json.data = { editorContent, userActivity };
      }
      sendMessage(JSON.stringify(json));
    }
  });

Broadcasting the message to all connected clients.

What happens when the browser is closed?

In that case, the WebSocket invokes the close event, which allows us to write the logic to terminate the current user’s connection. In my code, I broadcast a message to the remaining users when a user leaves the document:

connection.on('close', function(connection) {
    console.log((new Date()) + " Peer " + userID + " disconnected.");
    const json = { type: typesDef.USER_EVENT };
    userActivity.push(`${users[userID].username} left the document`);
    json.data = { users, userActivity };
    delete clients[userID];
    delete users[userID];
    sendMessage(JSON.stringify(json));
  });

Conclusion

**WebSockets **are one of the most interesting and convenient ways to achieve real-time capabilities in an application. It gives us a lot of flexibility to leverage full-duplex communications. I’d strongly suggest working with **WebSockets **before trying out Socket.IO and other available libraries.

Top Vue.js Developers in USA

Top Vue.js Developers in USA

Vue.js is an extensively popular JavaScript framework with which you can create powerful as well as interactive interfaces. Vue.js is the best framework when it comes to building a single web and mobile apps.

We, at HireFullStackDeveloperIndia, implement the right strategic approach to offer a wide variety through customized Vue.js development services to suit your requirements at most competitive prices.

Vue.js is an open-source JavaScript framework that is incredibly progressive and adoptive and majorly used to build a breathtaking user interface. Vue.js is efficient to create advanced web page applications.

Vue.js gets its strength from the flexible JavaScript library to build an enthralling user interface. As the core of Vue.js is concentrated which provides a variety of interactive components for the web and gives real-time implementation. It gives freedom to developers by giving fluidity and eases the integration process with existing projects and other libraries that enables to structure of a highly customizable application.

Vue.js is a scalable framework with a robust in-build stack that can extend itself to operate apps of any proportion. Moreover, vue.js is the best framework to seamlessly create astonishing single-page applications.

Our Vue.js developers have gained tremendous expertise by delivering services to clients worldwide over multiple industries in the area of front-end development. Our adept developers are experts in Vue development and can provide the best value-added user interfaces and web apps.

We assure our clients to have a prime user interface that reaches end-users and target the audience with the exceptional user experience across a variety of devices and platforms. Our expert team of developers serves your business to move ahead on the path of success, where your enterprise can have an advantage over others.

Here are some key benefits that you can avail when you decide to hire vue.js developers in USA from HireFullStackDeveloperIndia:

  • A team of Vue.js developers of your choice
  • 100% guaranteed client satisfaction
  • Integrity and Transparency
  • Free no-obligation quote
  • Portal development solutions
  • Interactive Dashboards over a wide array of devices
  • Vue.js music and video streaming apps
  • Flexible engagement model
  • A free project manager with your team
  • 24*7 communication with your preferred means

If you are looking to hire React Native developers in USA, then choosing HireFullStackDeveloperIndia would be the best as we offer some of the best talents when it comes to Vue.js.

Web Development Services

Web Development Services

As one of the best Web Application Development Company, it provides a fine quality mobile app development service at an affordable price. Especially, it encourage start-ups that have unique ideas, by offering a more competitive price

HireFullStackDeveloperIndia is rated as one of the top Web Application Development Company in India by various industry magazines and review sites. They have a right blend of award-winning designers, expert programmers and Google certified digital marketers which make them a unique one-stop solution for hundreds of our clients, spread across all countries.

A Good website reflects not only your business but also it is one of the main factors why a potential customer would convert into Client. A good website design helps increase traffic driving leads to grow business. The best web design company create a custom design for each corporate website so as to help them meet their business goals.

Get Quote: https://hirefullstackdeveloperindia.com/get-a-quote/