-
Notifications
You must be signed in to change notification settings - Fork 63
3: Control the logger from the server
In this assignment we'll use our socket-connection to tell the logger to run speedtests at regular intervals, and send the results back to the server, who'll pass it along to the client. In addition the server will ask the logger for the speedtest history when a new client connects, and pass this history along to the client. The image below illustrates how the client, server and logger events will be sent between the applications
Navigate to the 'every-bit-matters' folder. Type:
$ git checkout -f stage-3
Nice. You have now checked out the code required to start. Let's begin.
Let's start by making our logger run speedtests when it receives a logger:run event from the server. We can do this by adding a socket.on('logger:run', ....
handler, and move our speedtest code into the callback function of this handler.
This should make logger.js
look something like this:
logger/logger.js
var speedtest = require('speedtest-net');
var fileSystem = require('fs');
var test = speedtest();
var fileName = __dirname + '/history.json';
var history = JSON.parse(fileSystem.readFileSync(fileName));
var socket = require('socket.io-client')('http://localhost:3000/');
socket.on('connect', function () {
console.log('Logger is connected'); // Or 'Looksies! We got ourselves a user!'
});
socket.on('logger:run', function () {
console.log('Starting speedtest...');
test.on('data', function (data) {
var result = {
download: data.speeds.download,
upload: data.speeds.upload,
ping: data.server.ping,
date: Date.now()
};
history.push(result);
var jsonResult = JSON.stringify(history);
fileSystem.writeFile(fileName, jsonResult, function (err) {
if (err) {
console.log('Something went wrong: ' + err);
} else {
console.log('Speedtest finished');
}
});
});
test.on('error', function (err) {
console.error(err);
});
});
Now we have to update server.js
so a logger:run
event is emitted at regular intervals. One way of doing this, is by using a setInterval()
function. setInterval takes two arguments, the first is a callback function, specifying what to do, and the second is a number, representing the interval time in milliseconds.
Update server.js
to include the following:
server.js
...
setInterval(function () {
io.emit('logger:run');
}, 30000);
app.use('/', express.static('client'));
...
We also want the logger to send the result of the speedtest back to the server, so let's emit a server:results
event when the speedtest is done, and pass the results and history along with it.
logger/logger.js:
...
history.push(result);
socket.emit('server:results', history);
var jsonResult = JSON.stringify(history);
...
Now we need to handle the server:results
event on the server. Extend the 'connect' callback function to include a handler for server:results
, and emit a new client:display
event that the client can use to receive the data and display them.
server.js
io.on('connect', function (socket) {
console.log("Someone connected.");
socket.on('server:results', function (data) {
io.emit('client:display', data);
});
});
Now we just need to update client.js
to handle 'client:display' and print the results to the console.
client/client.js:
var socket = io();
socket.on('connect', function (data) {
console.log("I am connected");
});
socket.on('client:display', function (data) {
console.log(data);
});
It's tedious to wait until the next speedtest is finished, before data is shown in the client, so we want to send the history from the logger when a client connects.
To do this, we have to add an additional logger:history
handler to logger.js
.
logger/logger.js:
...
socket.on('logger:history', function () {
socket.emit('server:results', history);
});
...
We'll reuse the server:results
event, in order to pass the data to the server and client.
In addition, we'll have to extend the 'connect' callback function in server.js
to emit logger:history
.
server/server.js:
...
io.on('connect', function (socket) {
console.log('Looksies! We got ourselves a user!');
io.emit('logger:history');
...
You should now have a server.js
file looking something like this...
server/server.js:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
io.on('connect', function (socket) {
console.log('Looksies! We got ourselves a user!');
io.emit('logger:history');
socket.on('server:results', function (data) {
console.log("server:results");
io.emit('client:display', data);
});
});
setInterval(function () {
io.emit('logger:run');
}, 30000);
app.use('/', express.static('client'));
http.listen(port, function () {
console.log('Running our app at http://localhost:3000')
});
...a logger.js
file looking something like this...
logger/logger.js:
var speedtest = require('speedtest-net');
var fileSystem = require('fs');
var test = speedtest();
var fileName = __dirname + '/history.json';
var history = JSON.parse(fileSystem.readFileSync(fileName));
var socket = require('socket.io-client')('http://localhost:3000/');
socket.on('connect', function () {
console.log('Logger is connected');
});
socket.on('logger:history', function () {
socket.emit('server:results', history);
});
socket.on('logger:run', function () {
console.log('Starting speedtest...');
var test = speedtest();
test.on('data', function (data) {
var result = {
download: data.speeds.download,
upload: data.speeds.upload,
ping: data.server.ping,
date: Date.now()
};
history.push(result);
socket.emit('server:results', history);
var jsonResult = JSON.stringify(history);
fileSystem.writeFile(fileName, jsonResult, function (err) {
if (err) {
console.log('Something went wrong: ' + err);
} else {
console.log('Speedtest finished');
}
});
});
test.on('error', function (err) {
console.error(err);
});
});
...and a client.js
file looking something like this.
client/client.js:
var socket = io();
socket.on('connect', function (data) {
console.log("I am connected");
});
socket.on('client:display', function (data) {
console.log(data);
});
As we did in stage 2, start both the server and the logger, and open our web-page at http://localhost:3000/. Then open two terminals and have the browser ready.
Terminal 1. Run:
> node server.js
Server running on http://localhost:3000/
Terminal 2. Run:
> node logger/logger.js
Starting speedtest...
And finally open the web-page in the browser. Verify that the history is printed to the console in the browser, and that the server runs new speedtests. When the speedtest is done, check that the new resusts is printed in the browser.
Next assignment: Make-a-visualization-in-the-client