The traditional way to accomplish a real-time web dashboard is through automatically refreshing charts or long polling ajax requests. Socket.io is a Node.js library provides a duplex communication method between browsers and web servers using WebSocket. And as for those outdated clients that not support WebSocket, it can automatically fallback to traditional polling mechanisms. This article is a guide to implement a real-time web dashboard using Socket.io. You may need some basic knowledge about Node.js for better understanding.
Quick Start
Let us start with an example, a single chart that automatically updates in real-time. In this example, the data is stored in MySQL.
Server Side
The server should keep data updated and push data to client. Clients need two types of data: (1) complete data points for the chart when first connects to the server, (2) and updated data points for the chart after connected.
If you are using traditional databases like MySQL, you can query and cache the data every second like the following example.
But I highly recommend Redis as the storage system of real-time dashboards, you can store all your data that need real-time visualization in Redis.
Redis has a feature named SUBSCRIBE
, with which clients will be notified when data changes so that you don’t need to query periodically.
|
|
Client Side
Please see the corresponding code for the client as below. Highcharts a good choice for dynamic charts.
|
|
System Design
Now we consider a generic real-time web analytics system, with which we can easily add more charts and configure different data sources.
Rooms
The largest problem in the example above is that the server simply pushes all the data updates to all the clients.
In the real use case, each user only view one dashboard at a time, so how to send data only to those clients that have opened the related dashboards?
Socket.io’s Rooms and Namespaces can solve this problem easily.
We can change the above code like this to support rooms (not runnable, just to show the concept):
DataSychonizer
Then we need to decouple all these stuff, first create a class to handle the data sychonization for each query.
This one can only handle MySQL queries, but you can continue the decoupling to support more databases.
Data Model
Each room represents a chart. Each chart contains several series. Each series has a DataSynchronizer
.
Different charts can have common data series, thus each DataSynchronizer
should be registered to several rooms.
As for the user authorizations, you can bind them with charts or even series, depends on your needs.
Going into too much details is not the purpose of this article, I’d better publish a open-source project with my work later. Thanks for reading. :)