How to build a WebSocket server in Node.js?

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.

HTTP request
HTTP request

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.

WebSocket request
WebSocket request

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 -yCode language: Bash (bash)

Install Express.js in our project from the NPM registry using the following command:

npm install expressCode 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.jsCode language: Bash (bash)
Simple Express.js server
Simple Express.js server

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 wsCode 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.

New connection
New connection

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.

New message from the client
New message from the client

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.

New notification
New notification

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.

0/10000

No comments so far