What is WebSocket
The WebSocket protocol allows for two-way interactive communication sessions between the user’s browser (the client) and a server. Once the session is opened, the server can send messages to the client at will, eliminating the need for the client to poll the server.
Setting up the WebSocket
To build a WebSocket application, we need both a client and a server. This is essential for the two-way communication.
WebSocket Server
The server will be written using ExpressJS. When a WebSocket request is made to our server, we upgrade the connection to a WebSocket.
Express is a minimal and flexible Node.js application framework that provides a robust set of features for web and mobile applications. To install ExpressJS on your machine, run the following commands:
// Initialize Node.js and create a package.json file
npm init -y
// Install WebSocket library
npm install websocket
// Install ws library - a WebSocket implementation
npm install ws
// Install Express for creating a simple HTTP server
npm install express
// Alternatively, you can install all packages at once with this command
npm install ws express websocket
Now that we have successfully installed all the necessary packages, let’s create a file named index.js
at the root of your project. This index.js
will be our server-side JavaScript file.
Now let’s implement the server.
const express = require('express')
const app = express()
const server = require('http').createServer(app);
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server: server });
wss.on('connection', function connection(ws, request) {
ws.on('message', function incoming(message) {
console.log(message)
ws.send('Tobi from thoughtbot fusion team.');
});
});
app.get('/', (req, res) => res.send('Hello World!'))
server.listen(9000, () => console.log(`Lisening on port :9000`))
What’s going on here?
First, let’s break this code down into three parts: imports, functions, and events.
- In the first part, we import the packages we installed earlier. This is necessary as it is a convention with ExpressJS applications.
- There are several functions with distinct features on how they interact with the client.
- First, there’s
wss.on('connection')
, which is likely the first to be called. This is initiated when the client successfully connects to the server. ws.send(‘Tobi from thoughtbot fusion team’)
is another function provided by the socket package, allowing us to send a message to our client after establishing a connection.ws.on('message')
is another interesting function, allowing us to listen for messages that our client may send. Messages sent are instant and fast!
- First, there’s
app.get(‘/‘, (req, res) => res.send(‘Hello World!’))
defines the base route ‘/‘ to return ‘Hello World’. This means when you visit your site127.0.0.1:9000/
in a browser, it should return the text “Hello World,” which is great for testing if your server is running.Server.listen(9000, ()=> console.log('Listening on port : 9000'))
enables the server to listen on port 9000.
To start up the server, you can run:
node index
Once this is done, you should see in the Terminal a message saying “Listening on port: 9000”. We have successfully set up our WebSocket server, now listening on our local machine on port 9000.
Socket Client
Our client simply sends the request to our server and listens to events to know how to respond.
In our client folder, create a file index.html
, and another file called script.js
. The HTML file will be the frontend for the application, and script.js
will be the client-side JavaScript file containing our logic for connecting to our socket server.
In the index.html
file, paste:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thougthbot Client</title>
<script src="script.js"></script>
</head>
<body>
count is;
<h1 id="countContainer" onclick="onNumberClick()">0</h1>
</body>
</html>
What’s going on here?
- In the HTML file, we have an H1 tag displaying “Count is” and another one displaying the count. We also have a JavaScript import, which will contain the majority of our socket code, where we will connect to the socket server and communicate with it.
- The H1 tag also has an onclick event with
onNumberClick()
, so when we click on the H1 content, it will run the functiononNumberClick()
, which we will later define in ourscript.js
file.
Now let’s work on our script.js
file. Open it up and paste the following:
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:9000');
// Connection opened
socket.addEventListener('open', function (event) {
// socket.send('connected to server successfully')
});
// Listen for messages
socket.addEventListener('message', function (event) {
if (event.data) {
console.log(event.data)
const widgetParent = document.getElementById('countContainer');
widgetParent.innerHTML = event.data
}
});
const onNumberClick = () => {
socket.send('Hello From Client1!');
}
What’s going on here?
- We first initiate the socket with
const socket = new WebSocket('ws://localhost:9000');
. - This allows our client to also listen on port 9000, which is the same port we set on our socket server.
- We have event listeners, and some notable events are:
socket.addEventListener('message’)
This is fired anytime our server sends a message to our client. It comes with a callback that returns an object of data, which contains the message sent by the server (in our case, “Tobi from thoughtbot fusion team”).
- With this setup, when we load the HTML file, we will see the default 0 displayed on our browser. When we click on the 0, it will fire the
onNumberClick
function and send a message to our server, which will then send a message back to our client. - When we receive the message from our client, we will update the H1 tag with the message obtained from the server.
Conclusion
WebSockets are a great tool when the need for instant communication arises. They enables both the client and server to send messages to each other with zero latency. You can find the complete project on GitHub here