Skip to content

Lesson Continue working with Node.js Servers

Rafael J. Rodriguez edited this page Jan 6, 2017 · 2 revisions

Author

@Rafase282

Created by Rafase282

Github | FreeCodeCamp | CodePen | LinkedIn | Website | E-Mail

Continue working with Node.js Servers

HTTP Collect

Write a program that performs an HTTP GET request to a URL provided to you
as the first command-line argument. Collect all data from the server (not
just the first "data" event) and then write two lines to the console
(stdout).

The first line you write should just be an integer representing the number
of characters received from the server. The second line should contain the
complete String of characters sent by the server.

HINTS

There are two approaches you can take to this problem:

  1. Collect data across multiple "data" events and append the results
    together prior to printing the output. Use the "end" event to determine
    when the stream is finished and you can write the output.

  2. Use a third-party package to abstract the difficulties involved in
    collecting an entire stream of data. Two different packages provide a
    useful API for solving this problem (there are likely more!): bl (Buffer
    List) and concat-stream; take your pick!

http://npm.im/bl http://npm.im/concat-stream

To install a Node package, use the Node Package Manager npm. Simply type:

 $ npm install bl

And it will download and install the latest version of the package into a
subdirectory named node_modules. Any package in this subdirectory under
your main program file can be loaded with the require syntax without being
prefixed by './':

 var bl = require('bl')

Node will first look in the core modules and then in the node_modules
directory where the package is located.

If you don't have an Internet connection, simply make a node_modules
directory and copy the entire directory for the package you want to use
from inside the learnyounode installation directory:

file:///home/ubuntu/.nvm/versions/node/v4.1.1/lib/node_modules/learnyounod
e/node_modules/bl
file:///home/ubuntu/.nvm/versions/node/v4.1.1/lib/node_modules/learnyounod
e/node_modules/concat-stream

Both bl and concat-stream can have a stream piped in to them and they will
collect the data for you. Once the stream has ended, a callback will be
fired with the data:

 response.pipe(bl(function (err, data) { /* ... */ }))  
 // or  
 response.pipe(concatStream(function (data) { /* ... */ }))

Note that you will probably need to data.toString() to convert from a
Buffer.

Documentation for both of these modules has been installed along with
learnyounode on your system and you can read them by pointing your browser
here:

file:///home/ubuntu/.nvm/versions/node/v4.1.1/lib/node_modules/learnyounod
e/docs/bl.html
file:///home/ubuntu/.nvm/versions/node/v4.1.1/lib/node_modules/learnyounod
e/docs/concat-stream.html

My Solution

var http = require('http');
var uri = process.argv[2];
var str = '';
http.get(uri, function(response) {
  response.setEncoding('utf8');
  response.on("data", function(data) {
    str += data;
  });
  response.on('end', function() {
    console.log(str.length);
    console.log(str);
  });
});

Official Solution:

var http = require('http')  
     var bl = require('bl')  
     http.get(process.argv[2], function (response) {  
       response.pipe(bl(function (err, data) {  
         if (err)  
           return console.error(err)  
         data = data.toString()  
         console.log(data.length)  
         console.log(data)  
       }))    
     })

Juggling Async

This problem is the same as the previous problem (HTTP COLLECT) in that
you need to use http.get(). However, this time you will be provided with
three URLs as the first three command-line arguments.

You must collect the complete content provided to you by each of the URLs
and print it to the console (stdout). You don't need to print out the
length, just the data as a String; one line per URL. The catch is that you
must print them out in the same order as the URLs are provided to you as
command-line arguments.

HINTS

Don't expect these three servers to play nicely! They are not going to
give you complete responses in the order you hope, so you can't naively
just print the output as you get it because they will be out of order.

You will need to queue the results and keep track of how many of the URLs
have returned their entire contents. Only once you have them all, you can
print the data to the console.

Counting callbacks is one of the fundamental ways of managing async in
Node. Rather than doing it yourself, you may find it more convenient to
rely on a third-party library such as async or
after. But for this exercise, try and do it without
any external helper library.

My Solution

var http = require('http');

// Slice the arguments from command line to get only the urls.
var URLs = process.argv.slice(2);

// Counter to keep track of async responses.
var count = 0;

// Arry to store completed responses
var resArr = [];
URLs.forEach(getData);

// Makes the call and handles everythign.
function getData(url, index) {
  http.get(url, function(response) {
    var str = '';
    response.setEncoding('utf8');
    response.on("data", function(data) {
      str += data;
    });
    response.on('end', function() {
      resArr[index] = str;
      count++;
      if (count === URLs.length) {
        resArr.forEach(function(msg) {
          console.log(msg);
        });
      }
    });
  });
}

Official Solution:

var http = require('http')  
     var bl = require('bl')  
     var results = []  
     var count = 0  
     function printResults () {  
       for (var i = 0; i < 3; i++)  
         console.log(results[i])  
     }  
     function httpGet (index) {  
       http.get(process.argv[2 + index], function (response) {  
         response.pipe(bl(function (err, data) {  
           if (err)  
             return console.error(err)  

           results[index] = data.toString()  
           count++  

           if (count == 3)  
             printResults()  
         }))  
       })  
     }  

     for (var i = 0; i < 3; i++)  
       httpGet(i)

Time Server

Write a TCP time server!

Your server should listen to TCP connections on the port provided by the
first argument to your program. For each connection you must write the
current date & 24 hour time in the format:

 "YYYY-MM-DD hh:mm"

followed by a newline character. Month, day, hour and minute must be
zero-filled to 2 integers. For example:

 "2013-07-06 17:42"

HINTS

For this exercise we'll be creating a raw TCP server. There's no HTTP
involved here so we need to use the net module from Node core which has
all the basic networking functions.

The net module has a method named net.createServer() that takes a callback
function. Unlike most callbacks in Node, the callback used by
createServer() is called more than once. Every connection received by your
server triggers another call to the callback. The callback function has
the signature:

 function callback (socket) { /* ... */ }

net.createServer() also returns an instance of your server. You must call
server.listen(portNumber) to start listening on a particular port.

A typical Node TCP server looks like this:

 var net = require('net')  
 var server = net.createServer(function (socket) {  
   // socket handling logic  
 })  
 server.listen(8000)

Remember to use the port number supplied to you as the first command-line
argument.

The socket object contains a lot of meta-data regarding the connection,
but it is also a Node duplex Stream, in that it can be both read from, and
written to. For this exercise we only need to write data and then close
the socket.

Use socket.write(data) to write data to the socket and socket.end() to
close the socket. Alternatively, the .end() method also takes a data
object so you can simplify to just: socket.end(data).

Documentation on the net module can be found by pointing your browser
here:

file:///home/ubuntu/.nvm/versions/node/v4.1.1/lib/node_modules/learnyounod
e/node_apidoc/net.html

To create the date, you'll need to create a custom format from a new
Date() object. The methods that will be useful are:

 date.getFullYear()  
 date.getMonth()     // starts at 0  
 date.getDate()      // returns the day of month  
 date.getHours()  
 date.getMinutes()

Or, if you want to be adventurous, use the strftime package from npm. The
strftime(fmt, date) function takes date formats just like the unix date
command. You can read more about strftime at:
[https://github.com/samsonjs/strftime](https://github.com/samsonjs/strftim e)

My Solution

var net = require('net');
var port = process.argv[2];
var server = net.createServer(function(socket) {
  // socket handling logic
  var date = new Date();
  var out = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes();
  socket.end(out);
  socket.pipe(socket);
});

server.listen(port);

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]))

Getting Started

  1. Welcome!
  2. Contact
  3. Get Started with Free Code Camp

Front End Development Certification

  1. HTML5 and CSS
  2. Responsive Design with Bootstrap
  3. Gear up for Success
  4. jQuery
  5. Basic JavaScript
  6. Object Oriented and Functional Programming
  7. Basic Algorithm Scripting
  8. Basic Front End Development Projects
  9. Intermediate Algorithm Scripting
  10. JSON APIs and Ajax
  11. Intermediate Front End Development Projects
  12. Claim Your Front End Development Certificate

Data Visualization Certification

  1. SASS
  2. React
  3. React Projects
  4. D3
  5. Data Visualization Projects
  6. Claim Your Data Visualization Certificate

Back End Development Certification

  1. Upper Intermediate Algorithm Scripting
  2. Automated Testing and Debugging
  3. Advanced Algorithm Scripting
  4. AngularJS (Legacy Material)
  5. Git
  6. Node.js and Express.js
  7. MongoDB
  8. API Projects
  9. Dynamic Web Applications
  10. Claim Your Back End Development Certificate

Full Stack Development Certification

  1. Greefield Nonprofit Project 1
  2. Greefield Nonprofit Project 2
  3. Legacy Nonprofit Project 1
  4. Legacy Nonprofit Project 2
  5. Claim your Full Stack Development Certification

Coding Interview Preparation

  1. Whiteboard Coding Interview Training
  2. Critical Thinking Interview Training
  3. Mock Interview 1
  4. Mock Interview 2
  5. Mock Interview 3
Clone this wiki locally