How to build a WebSocket server in Node.js?
We are all familiar with and frequently use real-time messaging applications that use WebSocket in Node js. These have become a part of our everyday lives. But have you ever considered how these real-time apps are constructed?
In this article, we will learn about real-time data transfer using WebSockets. Furthermore, we will build a real-time messaging server using Node.js and the ws
library.
What is a WebSocket?
An HTTP request, as we already know, is used to send any message or data from our client to a server. The HTTP protocol is an application protocol that uses the TCP protocol to interconnect the client and server, which requires a three-way handshake. After the data transfer is complete, the connection is terminated.
Due to HTTP’s unidirectional nature, communication between the client and server is one-way only. Since HTTP is a stateless protocol, a three-way handshake must be completed after each request, lengthening the time it takes to respond. But we can’t afford any delays while communicating in real-time. As a result, we require the client and server to maintain a permanent connection. We can deal with this scenario with the aid of WebSockets.
In contrast to HTTP, WebSocket is a bidirectional, full-duplex protocol. Since it is a stateful protocol, it will keep the client and server connected until one of them decides to cut it off. Real-time communication between the client and the server is feasible because the connection is permanent.
What is ws library, WebSocket in Node js?
The Node ws
library is a client and server implementation for interfacing with WebSocket protocol. It is a beginner-friendly library with excellent performance and minimal overhead.
You may think of the client as a browser. However, in the case of the ws
library, the client here refers to another backend application communicating with our socket server. Also, we cannot use the ws
library in our browser. To make it work, the browser should have a native WebSocket
object.
Setting up WebSocket on the server-side
To better understand the setup, we will do it step-wise. In the following steps, we will set up the WebSocket server using Node.js and Express.js.
Installing Express.js on the server
Express.js is a well-liked open-source framework for building Node.js server-side applications. For this tutorial, we will use Express.js to mount our socket server on top of it.
To install Express.js we will use the NPM package manager. Initialize the directory and create a package.json
file using the following command.
npm init -y
Code language: Bash (bash)
Install Express.js in our project from the NPM registry using the following command:
npm install express
Code language: Bash (bash)
Express.js will be installed and listed as a dependency in our package.json
file.
Setting up Express.js on the server
Now, we will set up a simple Express.js server to mount our socket server on top of it.
Create an index.js
file inside the root of the project and write the following code inside the file:
const http = require('http')
const express = require('express')
const app = express();
const server = http.createServer(app)
server.listen(1337, function () {
console.log('Server running')
})
Code language: JavaScript (javascript)
We will use the following command to start our Express.js server:
node index.js
Code language: Bash (bash)
Installing ws library on the server
Now that we have our Express.js server set up, we can install the ws
library. Install the ws
library from the NPM registry using the following command:
npm install ws
Code language: Bash (bash)
The ws
library will be installed and listed as a dependency in our package.json
file.
Setting up WebSockets
Now that we have installed the ws
library using the NPM package manager, we can move on to set up a socket server. Our socket server will listen for connections for the clients and whenever a client connects to our socket server, a ‘connection’ event is fired. We will listen for the ‘connection’ event and whenever the event fires, we do some actions such as sending a response or initializing more event listeners for the connected client.
Firstly we’ll import the constructor from the ws
library that will create a new socket server instance for us. Write the following code inside the index.js
file:
const WebSocket = require('ws')
const wss = new WebSocket.Server({server});
wss.on('connection', function (ws) {
console.log('new connection')
})
Code language: JavaScript (javascript)
Here we create a new socket server using the Server
constructor provided by the library. In the constructor, we provided our server instance on top which we will mount the socket server.
After instantiating the socket server, we will listen for the connections, and on every connection, we run a callback that will log ‘New connection’ to the console. Also, the callback receives a client object that contains methods to emit socket events.
Setting up WebSocket on the client-side
Similar to the server-side setup, we will do the client-side setup step-wise. In the following steps, we will set up the WebSocket on the client using the native WebSocket
constructor.
Setting up the index.html
Create an index.html
file inside the root of the project. Write the following boilerplate inside the index.html
file:
<!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>WebSockets</title>
</head>
<body>
<h1>WebSockets Tutorial</h1>
</body>
</html>
Code language: HTML, XML (xml)
Serving the index.html file from our Express.js server
To serve the index.html
file from our Express.js server, we will create a root route and inside that root route, we will respond with the index.html
file. To accomplish this, we will utilize the sendFile()
method on the res
object. Inside the index.js
file, use the following code to create a new route and render out the HTML file:
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
})
Code language: JavaScript (javascript)
Instantiate a new WebSocket connection
Inside a <script>
tag in the index.html
file, we will write our JavaScript code to connect and interact with our socket server. To connect to our socket server, we will use the native WebSocket
constructor. It creates a new socket instance that connects to the socket server specified by the path we provide.
Write the following code inside a <script>
tag in the index.html
file:
const wsc = new WebSocket('wss://<YOUR-HOSTNAME>.app:1337');
Code language: JavaScript (javascript)
The path we provided uses the wss
protocol which is a Secure WebSocket protocol. You can use the ws
protocol if you are developing in a local environment using HTTP. But, since we are using Codedamn Playgrounds, which uses a secure HTTPS protocol, we must use the wss
protocol instead of the less secure ws
protocol.
Now, as soon as we start our socket server and navigate to the root route, our client will connect to the socket server and we will see a log message ‘New connection’ on the console.
Emitting events between the client and the server
We can now send messages between the client and the server after setting up WebSockets on both of them. Due to the event-driven nature of WebSockets, we would need to listen out for events on both the server and the client. And, to communicate between the two, we send certain events from one side and listen to them on the other.
Listening for events on the server-side
We launch a callback after a successful connection that takes a ws
object as an argument. The client’s information and a few methods for configuring event listeners on the server are both contained in the ws object.
Let us set up an event listener that listens for a message
event,
wss.on('connection', function (ws) {
console.log('new connection')
ws.on('message', function (data) {
console.log('New message: ' + data);
})
})
Code language: JavaScript (javascript)
Now, we will receive a console log on our server anytime a client emits a message
event.
Emitting events from the client-side
We can use the wsc
object that was returned from the constructor method to set up event listeners and emit various events we have defined on our server.
To emit an event from the client, write the following code inside the <script>
tag in the index.html
file:
wsc.onopen = function () {
wsc.send('Hello from client');
};
Code language: JavaScript (javascript)
Now, once we start the server and navigate to the root route, we will see a log ‘New connection’ on the console. Just after this log, another log ‘New message: Hello from client’ will appear.
Listening for events on the client-side
To listen for socket events on the client side, we will use the onmessage
method on the wsc
object returned from the constructor method.
Let us set up an event listener that listens for a notification
event,
wsc.onmessage = function (message) {
console.log('New notification: ' + message.data)
};
Code language: JavaScript (javascript)
Now, we will receive a console log on our client anytime the server emits a notification
event.
Emitting events from the server-side
To emit an event from the server to the connected client, we will use the send
method on the wss
object.
To emit an event from the server, write the following code inside the ‘connection’ event listener:
ws.send('Thanks for connecting');
Code language: JavaScript (javascript)
Now, once we start the server and navigate to the root route, we will see a log on the client’s console.
What’s next?
WS is a great library for creating a WebSocket server and doing all sorts of WebSocket-specific tasks. It’s extremely fast and manages everything with minimal performance overhead. But, as a beginner, it can be quite overwhelming at first, especially, for those who just started learning about WebSockets.
Socket.IO is an easy-to-use library similar to WS. Unlike WS, it is incredibly user-friendly for beginners and makes complicated tasks look relatively simple.
To learn how to create a WebSocket server using Socket.IO, you can refer to the following article on Codename:
How to use socket.io with Node.js – Node.js Socket.io Complete Tutorial
Conclusion
WebSocket in Node js is a bidirectional, full-duplex, and stateful protocol. Its most frequently used in real-time messaging applications. The Node ws
library is a client and server implementation for interfacing with WebSocket protocol. It has excellent performance and minimal overhead. But, for a beginner who just started learning about WebSocket in Node js, it can be quite overwhelming. An alternative could be to use Socket.IO, an easy-to-use library similar to WS.
You can find the full source code on Codedamn Playgrounds.
This article hopefully provided you with some new information. Share it with your friends if you enjoyed it. Also, please provide your feedback in the comments section.
Thank you so much for reading 😄
Sharing is caring
Did you like what Varun Tiwari wrote? Thank them for their work by sharing it on social media.
No comments so far
Curious about this topic? Continue your journey with these coding courses: