️ Blazing fast, dead simple, and minimal analytics solution for websites.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

108 lines
3.1 KiB

// require Express and Socket.io
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var path = require('path');
var config = require('./config.js');
// the object that will hold information about the active users currently
// on the site
var visitorsData = {};
app.set('port', (process.env.PORT || 5000));
// serve the static assets (js/dashboard.js and css/dashboard.css)
// from the public/ directory
app.use(express.static(path.join(__dirname, 'public/')));
// serve the index.html page when someone visits any of the following endpoints:
// 1. /
// 2. /about
// 3. /contact
app.get(/\/(about|contact)?$/, function (req, res) {
res.sendFile(path.join(__dirname, 'views/index.html'));
});
// serve up the dashboard when someone visits /dashboard
app.get('/dashboard', function (req, res) {
res.sendFile(path.join(__dirname, 'views/dashboard.html'));
});
io.on('connection', function (socket) {
if (socket.handshake.headers.host === config.host &&
socket.handshake.headers.referer.indexOf(config.host + config.dashboardEndpoint) > -1) {
// if someone visits '/dashboard' send them the computed visitor data
io.emit('updated-stats', computeStats());
}
// a user has visited our page - add them to the visitorsData object
socket.on('visitor-data', function (data) {
visitorsData[socket.id] = data;
console.log('New Visitor', visitorsData[socket.id]);
// compute and send visitor data to the dashboard when a new user visits our page
io.emit('updated-stats', computeStats());
});
socket.on('disconnect', function () {
// a user has left our page - remove them from the visitorsData object
console.log('Visitor has left the site', socket.id);
delete visitorsData[socket.id];
// compute and send visitor data to the dashboard when a user leaves our page
io.emit('updated-stats', computeStats());
});
});
// wrapper function to compute the stats and return a object with the updated stats
function computeStats() {
return {
pages: computePageCounts(),
referrers: computeRefererCounts(),
activeUsers: getActiveUsers()
};
}
// get the total number of users on each page of our site
function computePageCounts() {
// sample data in pageCounts object:
// { "/": 13, "/about": 5 }
var pageCounts = {};
for (var key in visitorsData) {
var page = visitorsData[key].page;
if (page in pageCounts) {
pageCounts[page]++;
} else {
pageCounts[page] = 1;
}
}
return pageCounts;
}
// get the total number of users per referring site
function computeRefererCounts() {
// sample data in referrerCounts object:
// { "http://twitter.com/": 3, "http://stackoverflow.com/": 6 }
var referrerCounts = {};
for (var key in visitorsData) {
var referringSite = visitorsData[key].referringSite || '(direct)';
if (referringSite in referrerCounts) {
referrerCounts[referringSite]++;
} else {
referrerCounts[referringSite] = 1;
}
}
return referrerCounts;
}
// get the total active users on our site
function getActiveUsers() {
return Object.keys(visitorsData).length;
}
http.listen(app.get('port'), function () {
console.log('listening on *:' + app.get('port'));
});