The WebSocket API enables us to establish bi-directional communication between a client — a browser and a server. And as a result, data can flow from client to server and server to client. Also, because WebSockets are always open, they allow real-time data flow in our application.
The first step of a WebSocket is for a client to send an HTTP request to the server — asking to open a connection. And if the server agrees, it will send a
101 Switching Protocols response— at which point the handshake is complete. So the TCP/IP connection is left open, thus, allowing a bi-direction flow of data between the server and the client with very low latency.
The WebSockets API allows several clients to connect to a server simultaneously. And this connection stays open until one of the parties drops off.
A typical application of the WebSockets API is a chat application, and the image below explains how this might work:
From the image above, each client—user browser is connected via a Websocket to the chat application server. So when a user types a message and clicks send, the message gets sent down to the server via the WebSocket connection. And the server in turn sends the message up the Websockets to all the clients. Consequently, they get a notification and see the message. The point to note here is that these communications are real-time. And that means no extra user request or Ajax request is being made at any time.
The WebSockets API enables us to build real-time features by establishing a two-way connection — via a socket, between a client and a server. So WebSockets have a lot of applications in programming these include:
- Chat application
- Multiplayer browser games
- Streaming applications
- Collaborative code editing software
- Live text for sports/news websites
- Real-time to-do apps with multiple users.
- Online drawing canvas applications
In this tutorial, we will learn more about WebSockets by building a chat application. And the prerequisites to gain the most from this article are outlined in the next section.
To follow along in the article, the following are required:
- Basic knowledge of Nodejs
- The latest version of Nodejs should be installed on your machine.
So to use the WebSockets API, we need some server code. And to get this we will build a Nodejs application.
Follow the steps below to bootstrap the Nodejs application:
- Create an application folder and from the folder initialize a Nodejs app by running the following code on your terminal:
npm init -y
- Install the required packages by running:
npm install express socket.io
And install dev-dependencies by running:
npm install -D nodemon
- Configure NPM Scripts by updating the
scriptsproperty in the
package.jsonfile as seen below:
- Now, set up the express server by creating an
srcfolder in the root directory. And in the
srcfolder, create an
index.jsfile with the following code:
In the code above, we serve a static HTML file — the
index.html file using the
res.SendFile method. So whenever a user points the browser to
index.html file is rendered to the browser. And we will create this
index.html file in the next section.
Also, in the code above, we set up an express server and implemented socket.IO on the server. And we will learn more about this in the next section.
But for now, start the dev-server by running
npm run dev and we get:
So with our application bootstrapped, in the next section, we will focus on building the chat app properly.
To establish a socket connection between the browser and our Nodejs application, we will use a library called
Socket.IO library is used by installing it both on the client and the server. And it enables socket connection between the client and the server — thus, it enables real-time bidirectional event-based communication between the server and the client.
Set up Socket.IO on the server
In our current application setup, we have implemented Socket.IO on the server using the
http.createrSever method from express.
When a client makes a connection with Socket.IO on the server, an event — called
connection is fired. And in our current setup, Socket.IO listens for this event using the
And when the
connection event fires, we call a callback and log
made socket connection and the socket
ID to the console.
This callback function takes a
socket object as an argument. And this
socket object refers to the instance of the
socket made between the client and the server. So if ten different clients connect to the server, each client would have its
Set up Socket.IO on the client
To set up Socket.IO on the client, create a
pubic folder in the root directory. And in the
public folder, create an
index.html file with the following code:
And on the browser we get:
Now we need to set up Socket.IO. Add this line of code to the
header section of the
index.html file to load the
The line of code above exposes an
io global, the endpoint
GET /socket.io/socket.io.js, and then connects.
Now to test if
socket.io-client was loaded successfully, above the closing
body tag, add the following code:
And refresh the browser. We get:
From the image above, we see that
made socket connection followed by the
socket id is logged to the console confirming that a Websocket connect has been established between the server and the client.
script tags above the
Emitting Messages With Socket.IO
In the previous sub-sections, we set up Socket.IO on the client and the server. But in this section, we will work on emitting messages via sockets.
In our chat app, when we send data — a chat message from a browser, through a socket to the server, the server receives that message and emits data — the message to all the clients that are connected to it.
So to handle this when a user clicks the send button, we will emit an event from the client to the server via the created socket.
To implement this, we need to get all the necessary DOM elements by adding the following code below the
// Query DOM comment in the
Next, we add an event listener to the send button to listen for
click events by adding the following code below the
// Emit events comment in the
In the code above, we added an event listener to the send button to listen for a
click event. And when a
click event occurs, the
socket.emit is called in the event handler callback.
socket.emit method takes two arguments: the name of the message — in this case,
chat and an object that contains the message or data we are sending to the server.
So on the server, we will add an event listener to listen for this sent event. And to do this modify the
io.on method in the
index.js file as seen below:
In the code above, we listen to the socket for the emission of the
chat message by calling the
socket.on method. And the
socket.on method takes two arguments: the
chat message and an event handler — callback.
Now we called
io.sockets.emit method within the callback function to send this message out to all the clients connected to the server via a WebSocket. And this enables everyone in the chat room can see the message.
io.sockets refers to all the WebSockets created by the different clients connected to the server. And
io.sockets.emit(‘chat’, data) emits a message — the data from the client that sent the message, to all the connected clients — in the
Now with our current setup, a user can send a message from the client to our server. And the server, upon receiving the message, emits the chat message back to all sockets in the
io.sockets collection. Thus, sending the message to all the connected clients.
Following this, on the client side, we need a way to display the received message on the browser. So add the following code below the
// Listen for events comment in the
script section in the
In the code above,
socket.on listens for a chat message and calls a callback — an event handler upon receiving the chat message. And in the event handler, we added code that renders the message to the server.
So with this, we have our basic chat functionality working. We can pass data from a client to a server and back from the server to all the clients connected via WebSocket.
In this section, we will use message broadcasting to notify other clients when a user is typing a message. And to implement this, add the following code below the
// Broadcast feedback when user types comment:
In the code above, we add an event listener that listens for a
keypress event to the message
input element. And when this event fires, we emit a
typing event from the event handler by calling
socket.emit — passing the user name as the data.
Now we need to handle this
typing event on the server and to do this modify the
io.connection method in the
index.js file as seen below:
In the code above, we listen to the socket for a
typing event. And once that event occurs we broadcast that event by calling
socket.broadcast.emit. This emits a
typing event and sends the received data to all connected client except the client that send the message.
Once again we need to handle this broadcasted message on the client side. And to do this, add the following code below the
// Listen for typing message comment in the
From the code above, each client listens on their socket for a
Finally, update clear the
feedback when the user finishes typing and clicks send. To this, modify the
socket.on method below the
// Listen for events comment as seen below:
Now once the
typing event is fired a message is printed to show that a user a typing as seen below:
In this article, we learned about the WebSocket API, a technology that enables a bidirectional flow of data between a server and a client with low latency.
If you are interested in the source code of the chat application we built, you can clone the repository on Github here.
Lastly, I hope after this tutorial you have learned enough to use WebSockets in your application.
So even if you feel like the proper decisions have been made, it’s always necessary to verify that this is indeed true and your users have a great experience with your product.
Dutfe utilizes pub/sub-services to process all of the ingested behavioral data from the browser in real time. As the data is being ingested, Dutfe allows you to watch user sessions as videos, allowing you to see exactly what happened during their journey.
Combining this visual information with all of the tech data from the browser such as errors, stack traces, network issues, debug data, etc. you can easily understand problematic areas in your product and efficiently resolve them.
There is a free trial if you’d like to give Dutfe a try.
Dutfe replaying a session