The only thing I have done before watching the codeschool course was to download and run the installation file
from https://nodejs.org.
It installs node and npm (the package manager for javascript).
You don't actually need to, but it's always nice to see something actually working.
Main points:
- non-blocking
- event loop - checking for events continuously (e.g. request, connection, close)
fs.readFile('/etc/hosts', function(err,contents) {
console.log(contents);
});
console.log('Doing something else');
or equivalently
var callback = function(err,contents) {
console.log(contents);
});
fs.readFile('/etc/hosts',callback);
The Hello World, which you can run with node hello.js
var http = require('http')
http.createServer(function(request,response) {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write("Hello!");
setTimeout(function(){
response.write("I am done.");
response.end()
}, 5000);
}).listen(8080);
Events
Many objects in node emit events, for example, fs.readStream emits a data
event,
and obviously we can listen for these events. The objects that can emit events inherit from
the EventEmitter class.
We can create custom EventEmitter:
var EventEmitter = require('events').EventEmitter;
var logger = new EventEmitter();
If you want to listen for error events:
logger.on('error',function(message){
console.log('Error: ' + message);
});
And to trigger the event:
logger.emit('error','An error');
In fact, earlier, when we called http.createServer(function(request,response) {...}),
this returns a http.Server object, which is an EventEmitter,
set to listen for request events (it is all in the documentation for node.js).
It is possible to write it this way:
var server = http.createServer();
server.on('request', function(request,response}{
response.writeHead(200);
response.write("Hello, this is dog");
response.end();
});
which is how you can explicitly bind several listeners on the same object.
Actually, you can listen to an event more than once:
var http = require('http');
var server = http.createServer();
server.on('request', function(request, response) {
response.writeHead(200);
response.write("Hello, this is dog");
response.end();
});
server.on('request', function(request, response) {
console.log("New request coming in...");
});
server.on('close', function(){
console.log("Closing down the server...");
});
server.listen(8080);
In the code above, whenever a request event happens, two things happen: send a response and write to console.
Streams
Streams is about how data is transferred back and forth. Streams can be readable, writable, or both. For example,
in the arguments for http.createServer, request is a readable stream, response
is a writable stream. These streams are kept open until we close the connection.
How do you read from a stream (e.g. how do you read request?). The request object is an EventEmitter,
and it emits two events: 'readable', when the server can start reading the data, and 'end', when the client finishes uploading
the data. Here is an example code:
http.createServer(function(request,response){
response.writeHead(200)
request.on('readable',function(){
var chunk = null;
while (null !== (chunk = request.read())) {
response.write(chunk);
}
});
request.on('end'), function() {
response.end();
});
}).listen(8080);
(the .write function implicitly does toString()). However, there is an even faster method, using pipe:
http.createServer(function(request,response) {
response.writeHead(200);
request.pipe(response);
}).listen(8080);
How is that useful? Well, the second main example is about reading and writing file:
var fs = require('fs'); // require the filesystem module
var file = fs.createReadStream("readme.md");
var newfile = fs.createWriteStream("readme_copy.md");
file.pipe(newFile);
You can for example do request.pipe(newfile), and when you
for example do
$ curl --upload-file readme.md localhost:8080it will upload readme.md to newfile. Here is a complete implementation of file upload with progress update:
http.createServer(function(request,response){
var newFile = fs.createWriteStream("readme_copy.md");
var fileBytes = request.headers['content-length'];
var uploadedBytes = 0;
request.on('readable', function() {
var chunk = null;
while(null !== (chunk = request.read())) {
uploadedBytes += chunk.length;
var progress = (uploadedBytes / fileBytes)*100;
response.write("progress: " + parseInt(progress,10) + "%\n");
}
});
request.pipe(newFile);
}).listen(8080);
To do list: play around with http://gulpjs.com.
No comments:
Post a Comment