learnyounode Lesson 10 – Time Server

For this lesson we need to create a Transmission Control Protocol (TCP) time server that writes the current date and time to the socket in 24 hour format.  In addition to an http module, node also has a TCP module that can be invoked with require(‘net’).  If you aren’t familiar with the TCP/IP networking model, we are drilling down to one level beneath the application layer, which we worked with in previous lessons with the http module.

To avoid frustration upfront, it is important to note that the data of the time server only needs to be written to the open socket on our server.  It does not need to be logged to the console.  To do this we only need to create a function that returns the date and time in the desired format, and call that function inside of the socket.end() method.

Another important point is that we need to zero fill our results.  That means 7:00 should be presented as 07:00.  There are modules that will do this for you, but the official solution for this problem employees a very function to properly format the time.

Official Solution

var net = require('net')

function zeroFill(i) {
  return (i < 10 ? '0' : '') + i
}

function now () {
  var d = new Date()
  return d.getFullYear() + '-'
    + zeroFill(d.getMonth() + 1) + '-'
    + zeroFill(d.getDate()) + ' '
    + zeroFill(d.getHours()) + ':'
    + zeroFill(d.getMinutes())
}

var server = net.createServer(function (socket) {
  socket.end(now() + '\n')
})

server.listen(Number(process.argv[2]))

As you can see, the official solution uses a function called zeroFill, which accepts ‘i’ as an argument.  The zeroFill function uses the conditional (ternary) operator to determine if a zero should be placed in front of a value.  If ‘i’ is less than 10, i < 10 evaluates to true, and zeroFill returns ‘0’ + i.  If ‘i’ is not less than 10, i < 10 evaluates to false, and zeroFill returns an empty string + ‘i’.

The conditional operator is not covered in codecademy.com modules to my recollection.  It is often times used in place of an if/else statement.  The basic syntax is below.

condition ? 'expression if true' : 'expression if false'

For more on the conditional, check out MDN’s writeup.

The official solution uses a second function called ‘now’ to properly format the date and time using the Date() object.  The Date() object is assigned to the variable ‘d’.  Then we get the full year with getFullYear() and concatenate it to the dash symbol.  After this we concatenate the result of zeroFill(d.getmonth()) and so on all the way down to minutes to get our properly formatted date.  The official solution breaks this into several lines for readability.

Next, we assign the net.createServer() method to the variable server.  The createServer() method accepts a callback as an argument, which accepts a socket.  Inside of the callback, we call the socket.end() method and pass now() plus a newline character to the end() method to write the date and time to the socket.

Finally, we listen with the listen() method for the port passed as the second command line argument.

If you want to log the date and time to the console instead of just writing it to the socket, you can use the code below.  However, the code below will not pass the lesson, so beware.

var net = require('net')
var port = process.argv[2]

function zeroFill (i) {
  return (i < 10 ? '0' : '') + i
}

function now () {
  var d = new Date()
  return d.getFullYear() + '-' +
    zeroFill(d.getMonth() + 1) + '-' +
    zeroFill(d.getDate()) + ' ' +
    zeroFill(d.getHours()) + ':' +
    zeroFill(d.getMinutes())
}

var server = net.createServer(function (socket) {
  socket.on('data', function (data) {
    console.log(data.toString())
  })
})
server.listen(port)

var socket = require('net').Socket()
socket.connect(port)
socket.end(now() + '\n')

To run this program, download the file and save it as timeServer.js.  Then, run it from the directory you saved it to.

node timeServer.js 8000

Hit control+c to exit.

Lesson 11

Contents