-
Notifications
You must be signed in to change notification settings - Fork 340
Lesson Continue working with Node.js Servers
Created by Rafase282
Github | FreeCodeCamp | CodePen | LinkedIn | Website | E-Mail
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.
There are two approaches you can take to this problem:
-
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. -
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
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)
}))
})
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.
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.
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)
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"
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)
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]))
Thanks for visiting, if you like this please feel free to star my repo, follow me or even contact me about contributing as it will be a lot of work and having help would be cool.
- HTML5 and CSS
- Responsive Design with Bootstrap
- Gear up for Success
- jQuery
- Basic JavaScript
- Object Oriented and Functional Programming
- Basic Algorithm Scripting
- Basic Front End Development Projects
- Intermediate Algorithm Scripting
- JSON APIs and Ajax
- Intermediate Front End Development Projects
- Claim Your Front End Development Certificate
- Upper Intermediate Algorithm Scripting
- Automated Testing and Debugging
- Advanced Algorithm Scripting
- AngularJS (Legacy Material)
- Git
- Node.js and Express.js
- MongoDB
- API Projects
- Dynamic Web Applications
- Claim Your Back End Development Certificate
- Greefield Nonprofit Project 1
- Greefield Nonprofit Project 2
- Legacy Nonprofit Project 1
- Legacy Nonprofit Project 2
- Claim your Full Stack Development Certification
- Whiteboard Coding Interview Training
- Critical Thinking Interview Training
- Mock Interview 1
- Mock Interview 2
- Mock Interview 3