|
|
|
// 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'));
|
|
|
|
});
|