Advertisement
  1. Code
  2. JavaScript

Start Using HTML5 WebSockets With a Node.js Server

Scroll to top
Read Time: 13 min

One of the coolest features in HTML5 is WebSockets. WebSockets allow us to communicate with a server, without the need for traditional AJAX requests.

In this tutorial, we are going to learn a lot about WebSockets. We'll build a practical example of a client and server that communicate via WebSockets. In this tutorial we'll be using Node.js for the server. If you want to use WebSockets with PHP, check out our companion post.

What are WebSockets?

WebSockets is a technique for two-way communication over one (TCP) socket, a type of push technology.

Why do we need WebSockets?

WebSockets are widely used when an application does not favour long polling. With long polling, the server constantly sends replies that may or may not have the required data. This data is required to keep the connection fresh, and alive. When a client receives the data, it checks and raises another request if needed. Of course, there are multiple benefits and use cases for long polling. But, long polling is not the best and most fancy technology for client-server communication. If the connection times out, a new one will be required. Also, long polling can result in very poor resource utilisation. 

These are two of the major reasons why a push technology was required. As suggested by its name, the server pushes data, whenever it has something for the client. That means the client does not have to raise periodic requests. 

Let's begin our demo with the web server. This is a simple demo that will help you get started with the entire technology. 

1. Building the Node.js Server

Step 1: Choose Your Library

When it comes to Node.js, you have a dozen libraries to choose from for building the server. My favourite is ws, an extremely simple library for building servers. The library allows us to create both servers and clients. How cool is that? 

Of course, the pre-requisite for using ws would be installing Node. So, don't forget to download and install Node.js in your system.

Next, you need to install the library. Well, that's a very simple job where you run the following command:

Then open most-loved code editor, and create a file called index.js.

Step 2: Create the WebSocket Server

First things first, you need to import the ws module. This is rather simple. You have to type the following line, and it would ensure to import ws into your application.

Next, you have to create a web socket server on a port. The client will communicate with the server through this port. In our case, the port number is 8081.

So, what should happen when the client wants to communicate with the server? We need to key down the logic for this. The ws module comes with multiple events for each of the following changes in state:

  • open
  • close
  • message
  • connection
  • upgrade
  • ping

Also, the module comes with some functions to trigger and handle the above events:

  1. on
  2. send
  3. onerror

In our simple server, we would emit the connection event whenever the client connects. To emit one of the events, we can make use of the on function.

Incase, there is an error, the onerror function can be used. Here is a brief example, of how these functions can be used.

The basic skeleton of our WebSocket server, which opens and closes port 8081 for the client to connect with is as below:

Step 3: Receiving a Message

A server can only perform one of these two operations with a client: send a message or receive a message. Firstly, let's see how to receive a message from a client. Once the client and server connection has been established, the server can receive a message using the message function. 

Websocket communication always happens with frames. These are data fragments, which get transferred from client to the server, or vice versa. And, the data fragments can be in the following formats:

  • Text frames: these contains data in the form of raw text.
  • Binary data frames: these contain binary pieces of data.
  • Ping-pong frames: these are mostly used to check if the connection was established between the client and server. The browser often takes the responsibility of responding to these messages.
  • Connection close frames: these are used to handshake the connection closing.

When the browser talks to the server, which happens in our case, the text or binary frames are used. the .send() functionality of the client tends to send messages as binary or text data. This includes various formats like ArrayBuffer, and Blob as well. You don't have to configure anything to send data in a specific format. Just send it out and decode at the server. 

Meanwhile, if you want to explicitly mention the type of frame, use the .binaryType property of the socket.

If you want to decode the buffer data, to string, you can use the following function. Here we make use of Buffer.from(), followed by .toString() to convert the buffer to string.

Step 4: Sending a Message to the Client

The next functionality of the server is to send a message to the client. For this, we make use of the ws.send() function.

Now that we have the basics of our server identified, and defined, let's build the application where the server sends a message to the client, whenever the client connects with it. In the below piece of code, the server continues to send 'hello world' every second, until the client disconnects. 

This is how simple it is, to send a message to the client.

Step 5: Running the Server

Finally, you need to run the server. For this, you need to open a terminal window, type the following command, and leave the server running. Don't forget to open the terminal in the folder, where the index.js created in step 1 is present.

And, the entire server code to connect, disconnect, send and receive messages, appears as below:

2. Building the Client

Now, that the server is up and running, it is time to build the client. For this, create another Node project with the following files: 

Step 1: Install the Library

Just like, how we installed ws to build our server, you have to install ws in the client package, as well. Your package.json, should have the following dependency:

Step 2: Connecting to the Web Server

In order to connect with the web server, we have to initialise a new WebSocket. And, the web socket needs to connect to the port defined while building the web server. In our case, it will again be 8081.

There are three important parts to the host URL.

  • scheme: ws
  • host: localhost
  • port: 8081

With new WebSocket(url), the connection happens immediately. During the process of establishing the connection, the client (aka browser) uses headers to ask the server if WebSockets are supported or not. If the server responds with a'yes, the connection is established, and the two start talking. The protocol used is the WebSocket Protocol. Here, we don't use the HTTP Protocol at all!

Here are few of the request headers, in our client-server connection.

  • Connection: upgrade says that the client needs a switch in protocol.
  • Upgrade: websocket mentions that the protocol requested is "websocket".
  • Sec-WebSocket-Key is a browser generated key. This is a random number that makes sure that the server supports the WebSocket protocol. It also prevents various proxies from caching any conversation made between the client and server.
  • Sec-WebSocket-Version identifies the version of the WebSocket protocol. The most recent one is 13.

If the server has agreed to establish a connection, the response would be 101. And the response headers will be as below:

Sec-WebSocket-Accept has a key generated using a very special algorithm. The moment the browser (aka client) notices this key, it knows that the server actually supports the WebSocket protocol. Henceforth, data can be transferred in the form of frames. 

You cannot emulate WebSocket Handshakes. You cannot use fetch or XMLHttpRequest to make a HTTP request. Why? Because JavaScript does not have the permission to set the headers mentioned above.

Step 3: Define the WebSocket Events

Before we define our web socket events, you need to have a better understanding about them. In our client, we would use three different events:

  • onOpen: Functionality to be triggered when the socket opens.
  • onMessage: Functionality to be triggered when a message is received from the server.
  • onClose: Functionality to be triggered when the server is closed.
WebSocket EventsWebSocket EventsWebSocket Events

The above events have to be called using the WebSocket object.

Our demo, the client will connect with the server and display any message received from the server on the HTML page. Likewise, any change in state from connect to disconnect will be printed to the HTML page. To achieve this, we will write a connect method, which will implement the Web Socket events accordingly.

You can see that our connect function has a try/catch block. It is good coding practice, to enclose all server communication within the try/catch block. If something goes wrong, we need to have a fallback strategy. And, try/catch offers this to us! It provides the client a way of letting the user know that something has gone wrong with the connection. Also it is a great place to debug the overall flow. 

In the above method, the onmessage function takes the role of printing any message from the server on the HTML page. 

Step 4: The Bridge

The connect function does not start the client-server connection immediately. We can see that the websocket is defined, but the definition of the messageDiv, connectBtn, disconnectBtn, and hostUrl seems to be coming from somewhere else. 

We have broken the client code into two sections, init() and connect(). It is the responsibility of the init function to load all these variables. And, the init function has to be loaded when the page loads. The definition of the init function is given below.

Step 5: The Client Page

The client page is rather simple and straight forward. We are going to have the following:

  • a div where the message from the server will be loaded
  • two buttons to connect, and disconnect from the server

Here is a HTML code, for building this page. It needs to be entered in index.html:

WebSocket Client DemoWebSocket Client DemoWebSocket Client Demo

As soon as the connection is established, the client will receive 'Hello World' from the server. Now, the page will appear as below.

Websocket client demoWebsocket client demoWebsocket client demo

The complete piece of code in client's index.js is as following:

Step 6: Sending Data From Client to Server

Until, the above piece of code, you will be able to send data from the server to the client. In order to send data from the client to the server, you have to implement few more lines of code.

We are going to add a text box, in our HTML page where the user can input data. And a button to send the content of the text box to the server when clicked.

With text inputWith text inputWith text input

When the button is clicked, the following method gets invoked to send a message to the server. Since the default frame of the web socket is used, the message will be send as a Buffer

Upon clicking Send Message, the following gets displayed in the server's console, as below: 

Step 7: Running the Client

To run the client, you don't have to do much. You need to open index.html in your favourite browser, and then click on Connect to establish the connection with the server.

That's it!

Conclusion

This brings us to the end of our tutorial on WebSockets using HTML and Javascript (NodeJS). WebSockets are extremely exciting, and have changed drastically in the past few years. WS is just one of the many web socket libraries to choose from. You have to keep an eye for the W3C WebSocket API, to learn all about the newest changes to this PUSH technology. 

WebSocket is a persistent way of establishing a browser-server connection. These don't have cross-origin limitation, and are supported in all modern browsers. The API is simple with methods like .send and .close

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.