-
Notifications
You must be signed in to change notification settings - Fork 64
2: Wire it all up with socket.io
In this assignment we'll connect the client, server and logger together using socket.io.
Navigate to the 'every-bit-matters' folder. Type:
$ git checkout -f stage-2
Nice. You have now checked out the code required to start. Let's begin.
Socket-io is a library used for socket-communication. A socket is different from a regular GET or POST, since it allows both the client to communicate with the server and the server to communicate with the client.
First we have to install both socket.io, and socket.io-client.
> npm install socket.io --save
> npm install socket.io-client --save
To enable the server to use socket.io, we have to update our express server to expose the http-interface. We have to do this since socket.io is designed to work against this interface. In our previous examples, all this was handeled "under the hood", and a full explanation of how this works in detail is beond the scope of this workshop, but have a look at the socket.io docs if you're interested in learning more about this.
We start by requiring http from node, and wire it to our express server. Then we require socket.io, and pass it the reference to http.
server.js
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
...
We also have to use http.listen()
, instead of app.listen()
.
server.js
http.listen(...);
Finally we add a connection-handler to the connect
event. The connect
event is fired when a client connects to our server, and we add a callback function that prints a message to the console when this happens.
server.js
...
var port = process.env.PORT || 3000;
io.on('connect', function (socket) {
console.log('Looksies! We got ourselves a user!');
});
app.use('/', express.static('client'));
...
Our updated server should look something like this:
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!');
});
app.use('/', express.static('client'));
http.listen(port, function () {
console.log('Server running on http://localhost:' + port + '/');
});
When the server is updated, we can connect the client, and the logger. Socket.io treats all connections as if they are clients. Therefore, we can write similar code for both the logger and client.
We'll start by updating the client. Open index.html
, and update the content with the following:
client/index.html
<!DOCTYPE html>
<html>
<head>
<title>Every Bit Matters</title>
<link href="css/client.css" rel="stylesheet">
<script src="socket.io/socket.io.js"></script>
</head>
<body>
<h1>Your Own VIPWA (Very Important Personal Web Application)</h1>
<script src="client.js"></script>
</body>
</html>
This will include the socket.io web-client, and our own client.js
script, that will contain the socket connection code.
client.js
is included at the bottom of the file, since we might want to access parts of the HTML-document in our script later. (foreshadowing!)
Then we'll add the following connection code to client.js
.
client/client.js
var socket = io();
socket.on('connect', function (data) {
console.log("I am connected");
});
This time we can create a new socket directly, no fancy configuration with express needed, and as with the server we add a connection-handler, that prints a message to the console when a connection has been established.
The only thing we have left now, is to connect the logger. This is done almost exactly the same way as for the client.
logger/logger.js
...
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');
});
console.log('Starting speedtest...');
...
The client had the luxury of running on the same server as the socket.io server, and used it's standard connecting scheme. As the logger has no affiliation with the server, we need to specify the socket.io server URL.
The updated logger.js
should 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');
});
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);
});
To validate the connection, we need to initiate both the server and the logger, and navigate to the web-app at http://localhost:3000/. For this to be done, we run two terminals at the same time.
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 our messages is printed in all terminals, and the console in the browser.
Next assignment: Control the logger from the server