Building a real-time web app in NodeJS Express with Socket.io library | by Charmaine Chui | Towards Data Science

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:
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.
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:
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_arrivalsand 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)
Following up from point 3 of the above implementation, recall that the namespaces bus_arrivalsand get_bus_arrivals_info are specified for 2 web socket channels:
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:
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.
Finally, after deciding which data fields of the Bus Arrival information should be included for display, the following is the layout I decided to implement:
And there you go! The Bus ETAs would now be re-rendered every 10 seconds (can be customised) to reflect the latest updates! 🤩
FYI: For the full source code please head to my GitHub repo. The web app is currently deployed at: https://sg-transportation.herokuapp.com/
Hope the above illustrations of implementing Socket.io in NodeJS has been useful and many thanks for reading! ❤ Please follow me on medium if you would like to read my other upcoming recounts of tackling challenges at work (both people and technical issues)! Would really appreciate it 😀