Fix frontend not updating publicConfig.json

This changes the handshake sequence to use “bootTime” (a unique key
based off the time) to make sure the frontend configuration matches the
current one. If not, the client pulls the update and validates before
requesting the listing.
This commit is contained in:
Cryptkeeper 2016-02-06 18:26:29 -06:00
parent 143e99876a
commit 798dda8f12
5 changed files with 86 additions and 44 deletions

34
app.js

@ -142,22 +142,9 @@ function startServices() {
logger.log('info', '%s connected, total clients: %d', client.request.connection.remoteAddress, connectedClients); logger.log('info', '%s connected, total clients: %d', client.request.connection.remoteAddress, connectedClients);
setTimeout(function() { // We send the boot time (also sent in publicConfig.json) to the frontend to validate they have the same config.
client.emit('setGraphDuration', config.graphDuration); // If so, they'll send back "requestListing" event, otherwise they will pull the new config and retry.
client.emit('bootTime', util.getBootTime());
// Send them our previous data, so they have somewhere to start.
client.emit('updateMojangServices', mojang.toMessage());
// Remap our associative array into just an array.
var networkHistoryKeys = Object.keys(networkHistory);
networkHistoryKeys.sort();
// Send each individually, this should look cleaner than waiting for one big array to transfer.
for (var i = 0; i < networkHistoryKeys.length; i++) {
client.emit('add', [networkHistory[networkHistoryKeys[i]]]);
}
}, 1);
// Attach our listeners. // Attach our listeners.
client.on('disconnect', function() { client.on('disconnect', function() {
@ -172,6 +159,21 @@ function startServices() {
client.emit('historyGraph', graphData); client.emit('historyGraph', graphData);
} }
}); });
client.on('requestListing', function() {
// Send them our previous data, so they have somewhere to start.
client.emit('updateMojangServices', mojang.toMessage());
// Remap our associative array into just an array.
var networkHistoryKeys = Object.keys(networkHistory);
networkHistoryKeys.sort();
// Send each individually, this should look cleaner than waiting for one big array to transfer.
for (var i = 0; i < networkHistoryKeys.length; i++) {
client.emit('add', [networkHistory[networkHistoryKeys[i]]]);
}
});
}); });
startMainLoop(); startMainLoop();

@ -1,10 +1,15 @@
var graphs = {}; var graphs = [];
var lastPlayerEntries = {}; var lastPlayerEntries = [];
var historyPlot; var historyPlot;
var displayedGraphData; var displayedGraphData;
var hiddenGraphData = []; var hiddenGraphData = [];
var isConnected = false;
var mojangServicesUpdater;
var sortServersTask;
function updateServerStatus(lastEntry) { function updateServerStatus(lastEntry) {
var info = lastEntry.info; var info = lastEntry.info;
var div = $('#status_' + safeName(info.name)); var div = $('#status_' + safeName(info.name));
@ -117,6 +122,37 @@ function setAllGraphVisibility(visible) {
} }
} }
function validateBootTime(bootTime, socket) {
$('#tagline-text').text('Validating...');
console.log('Remote bootTime is ' + bootTime + ', local is ' + publicConfig.bootTime);
if (bootTime === publicConfig.bootTime) {
$('#tagline-text').text('Loading...');
socket.emit('requestListing');
if (!isMobileBrowser()) socket.emit('requestHistoryGraph');
isConnected = true;
// Start any special updating tasks.
mojangServicesUpdater = setInterval(updateMojangServices, 1000);
sortServersTask = setInterval(sortServers, 10000);
} else {
$('#tagline-text').text('Updating...');
$.getScript('/publicConfig.json', function(data, textStatus, xhr) {
if (xhr.status === 200) {
validateBootTime(publicConfig.bootTime, socket);
} else {
$('#tagline').attr('class', 'status-offline');
$('#tagline-text').text('Failed to update! Refresh?');
}
});
}
}
$(document).ready(function() { $(document).ready(function() {
var socket = io.connect({ var socket = io.connect({
reconnect: true, reconnect: true,
@ -124,25 +160,13 @@ $(document).ready(function() {
reconnectionAttempts: 10 reconnectionAttempts: 10
}); });
var mojangServicesUpdater; socket.on('bootTime', function(bootTime) {
var sortServersTask; validateBootTime(bootTime, socket);
});
socket.on('connect', function() {
$('#tagline-text').text('Loading...');
if (!isMobileBrowser()) {
socket.emit('requestHistoryGraph');
}
});
socket.on('disconnect', function() { socket.on('disconnect', function() {
if (mojangServicesUpdater) { if (mojangServicesUpdater) clearInterval(mojangServicesUpdater);
clearInterval(mojangServicesUpdater); if (sortServersTask) clearInterval(sortServersTask);
}
if (sortServersTask) {
clearInterval(sortServersTask);
}
$('#tagline').attr('class', 'status-offline'); $('#tagline').attr('class', 'status-offline');
$('#tagline-text').text('Disconnected! Refresh?'); $('#tagline-text').text('Disconnected! Refresh?');
@ -157,6 +181,8 @@ $(document).ready(function() {
$('#big-graph').html(''); $('#big-graph').html('');
$('#big-graph-checkboxes').html(''); $('#big-graph-checkboxes').html('');
$('#big-graph-controls').css('display', 'none'); $('#big-graph-controls').css('display', 'none');
isConnected = false;
}); });
socket.on('historyGraph', function(rawData) { socket.on('historyGraph', function(rawData) {
@ -333,11 +359,11 @@ $(document).ready(function() {
} }
}); });
socket.on('updateMojangServices', updateMojangServices); socket.on('updateMojangServices', function(data) {
if (isConnected) {
// Start any special updating tasks. updateMojangServices(data);
mojangServicesUpdater = setInterval(updateMojangServices, 1000); }
sortServersTask = setInterval(sortServers, 10000); });
$(document).on('click', '.graph-control', function(e) { $(document).on('click', '.graph-control', function(e) {
var serverIp = $(this).attr('data-target-network'); var serverIp = $(this).attr('data-target-network');

@ -4,7 +4,7 @@
"/images/compass.png": "assets/images/compass.png", "/images/compass.png": "assets/images/compass.png",
"/js/site.js": "assets/js/site.js", "/js/site.js": "assets/js/site.js",
"/js/util.js": "assets/js/util.js", "/js/util.js": "assets/js/util.js",
"/js/config.js": "assets/js/config.js", "/js/graph.js": "assets/js/graph.js",
"/css/main.css": "assets/css/main.css", "/css/main.css": "assets/css/main.css",
"/favicons/hypixelpe.png": "assets/images/favicons/hypixelpe.png", "/favicons/hypixelpe.png": "assets/images/favicons/hypixelpe.png",
"/favicons/mineplex.png": "assets/images/favicons/mineplex.png", "/favicons/mineplex.png": "assets/images/favicons/mineplex.png",
@ -16,7 +16,7 @@
"Mobcrush Land": "/favicons/mobcrush.png" "Mobcrush Land": "/favicons/mobcrush.png"
}, },
"site": { "site": {
"port": 80, "port": 8080,
"ip": "0.0.0.0" "ip": "0.0.0.0"
}, },
"rates": { "rates": {

@ -4,6 +4,7 @@ var url = require('url');
var mime = require('mime'); var mime = require('mime');
var io = require('socket.io'); var io = require('socket.io');
var util = require('./util');
var logger = require('./logger'); var logger = require('./logger');
var config = require('../config.json'); var config = require('../config.json');
@ -65,7 +66,8 @@ function handleRequest(req, res) {
var publicConfig = { var publicConfig = {
categories: categories, categories: categories,
graphDuration: config.graphDuration, graphDuration: config.graphDuration,
servers: servers servers: servers,
bootTime: util.getBootTime()
}; };
res.write('setPublicConfig(' + JSON.stringify(publicConfig) + ');'); res.write('setPublicConfig(' + JSON.stringify(publicConfig) + ');');

@ -3,7 +3,9 @@ var logger = require('./logger');
var config = require('../config.json'); var config = require('../config.json');
var servers = require('../servers.json'); var servers = require('../servers.json');
var serverNameLookup = {}; var serverNameLookup = [];
var bootTime;
// Finds a server in servers.json with a matching IP. // Finds a server in servers.json with a matching IP.
// If it finds one, it caches the result for faster future lookups. // If it finds one, it caches the result for faster future lookups.
@ -136,4 +138,14 @@ exports.convertPingsToGraph = function(sqlData) {
logger.info('Converted data structure in ' + (exports.getCurrentTimeMs() - startTime) + 'ms'); logger.info('Converted data structure in ' + (exports.getCurrentTimeMs() - startTime) + 'ms');
return graphData; return graphData;
};
exports.getBootTime = function() {
if (!bootTime) {
bootTime = exports.getCurrentTimeMs();
logger.info('Selected %d as boot time.', bootTime);
}
return bootTime;
}; };