Building a real-time web app in NodeJS Express with Socket.io library
By: Charmaine Chui
Tags: Real Time Analytics, Socket Programming, Geospatial, Web App Development, Nodejs

Building a real-time web app in NodeJS Express with Socket.io library

Use-Case: My Bus Route Visualisation Site

To gain a deeper understanding of the travelling patterns among public transportation commuters, I had been tasked a few months ago to perform an analysis which involves trip chaining a series of bus journeys. While I had initially built a Bus Route Visualisation Site for the sole purpose of exporting custom bus route data based on specific Origin-Destination pairings selected:

Screenshot by Author | Displays the site functionality of enabling selection of origin-destination bus stops

Screenshot by Author | The Origin-Destination bus route data selected can be exported on the web app

I later decided to further explore and leverage on the data provider’s public API which includes returning the real-time bus arrival timings at any specific bus stop. In short, I was curious about what other data fields the API includes in its real-time responses 🤔

While there are alternative libraries which are capable of integrating real-time data streaming within a web app, my primary reason for implementing Socket.io is because it not only serves its functionality of establishing a Web socket bidirectional connection between Server + Client but also, both Server & Client code implementations are written in JavaScript so there is no need to switch back and forth between 2 languages while coding the application’s backend and frontend.

Server-Side Implementation of Socket.io

For starters, within an Express NodeJS web app, the server-side of the code conventionally refers to the app.js/server.js file i.e. the entry point of the web application where an instance of Express.js is being initialised. After installing the NodeJS Socket.io library via npm install socket.io , the server-side code implementation is as follows:

So there are a few crucial points that should be noted in the above code snippet:

1. The library socket.io is imported via:

const socketio=require("socket.io")

2. Any web socket instance has by default the namespace disconnect — which emits a message back to the server if the instance has disconnected from the frontend (usually due to disconnection from its web server)

3. The custom namespaces bus_arrivals and get_bus_arrivals_info shall subsequently correspond to the exact same namespaces (KIV) from the client-side such that in the event multiple socket channels are present, the web socket instance would be able to identify based on namespaces which messages to emit to which channels.

4*. After the app instance is created from Express NodeJS library, a server instance which wraps around the app instance is initialised via:

const server = http.createServer(app)

⚠ This is extremely important to note since both app and server instances have completely separate functions. While contents of the web app are being served by the app instance, the actual web socket connection is in fact running on the server instance which is denoted by:

const io = socketio(server)

Client-Side Implementation of Socket.io

Following up from point 3 of the above implementation, recall that the namespaces bus_arrivals and get_bus_arrivals_info are specified for 2 web socket channels:

Illustration by Author | The server receives a request via socket channel [bus_arrivals] from the client to know which bus stop information the server should retrieve. The server then proceeds to make an API call to retrieve the bus arrival information of that particular bus stop. Finally, The API response is returned to the frontend for rendering via web socket channel [get_bus_arrival_info]

To enable a client-side instance of the web socket to be initialised, the JavaScript browser library for socket.io must be included:

<script type=”text/javascript” src=”js/socket.io.js”></script>`

before the following code snippet to implement Socket.io is embedded within the browser’s JavaScript content:

⚠ Please note that the version of both the NPM Socket.io package installed for the server-side and the JavaScript library imported on the browser side must be compatible. In my web application, the versions of the Socket.io libraries I have used are:

Server-Side NPM Package: socket.io v4.1.3

Client-Side JavaScript Library: Socket.IO v4.1.3

For more information to determine if the NPM package you have installed is compatible with the JavaScript library you have imported on the browser, please refer to Socket.io’s official site.