I'm still somewhat confused by how node callbacks work. Looking at this tutorial: http://www.nodebeginner.org/
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
My understanding is that the request and response parameters are passed when the server receives a request. However, I'm not sure how you would tell by the syntax. Does the createServer function not return anything until it actually receives a request, upon which it returns two objects, the request and the response?
No, the createServer method returns immediately, with a new web server object. That web server object's listen method is then immediately called, and the server begins listening for connections on port 8888. The listen call returns immediately as well; you can demonstrate this by adding a console.log('here'); on the next line and seeing how it writes to the terminal as soon as you run the script. As a result of the listen call, any time a new HTTP request is made to port 8888, the callback which was the sole argument to createServer is called to handle the request.
Since Node runs in a single thread (more or less), any operation that would block that thread--like waiting around for a server connection, or a database query, or a response to a remote request--is handled asynchronously, through the use of callbacks like the one in your example.
Related
I recreated a simple http server setup I found online (see below), but cannot get the request.on("end", ...) to work. It works fine if I comment that part out, but I really want to understand why it isn't working. Please help. Thanks!
Correct me if I'm wrong, but I think what's happening here is as follows:
var http = require('http'); pulls all "exports" from the node.js http module and allows them to be used in this node.js simple server code.
http.createServer instantiates an object of the http.Server class/type.
.listen(8080) opens the server for connections at port 8080 on localhost.
When a user attempts to connect at port 8080, the Server object emits a request event (which is itself another event.emitter object?). That event invokes the anonymous listener function and passes request object to it.
request.on("end", ...) adds a listener function to the request object that looks specifically for an eventName "end". If the end event is emitted by the request object, then the anonymous function is invoked (the response is written).
Here is the code I used: https://code.tutsplus.com/tutorials/nodejs-for-beginners--net-26314
var http = require("http");
http.createServer(function(request, response) {
request.on("end", function() {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end("Hello HTTP!");
});
}).listen(8080);
Node.js's website says that the framework "exits the event loop when there are no more callbacks to perform."
What I haven't found clearly explained anywhere is what keeps the event loop running once you initiate an I/O module that is waiting for input. For example, in this canonical "Hello World" HTTP server example, Node.js continues listening indefinitely for incoming HTTP requests:
require('http').createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World\n');
}).listen(8080);
While there is always the potential for a callback to the implicit request event handler, until an actual HTTP request comes in, there's no event being handled. Does this mean that the statement from the Node.js website isn't strictly true? Or is there some nuance here that I am missing?
The nuance is that there are callbacks "under the hood" as well.
In this case, the HTTP server is waiting for incoming connections on a TCP port, and until that port is explicitly closed (server.close()), this adds to the list of pending callbacks.
You don't even have to define a request handler to demonstrate this:
require('http').createServer().listen(8080);
And this shows what happens when you close the port after a few seconds:
var server = require('http').createServer().listen(8080);
setTimeout(function() {
server.close();
}, 2000);
I am learning node.js, and I am not managing to find a direct answer to this question. How does node.js deal with HTTP incoming requests, if they come in virtually at the same time? Let's say that one HTTP request comes in at a given time. As a result, the value of a global variable might change. However, at virtually the same time, another request comes in. In order to service the new request, the value of that one global variable is needed, but the code for the first request is still executing. How does node react to this?
Node.js processes the request one after the other. There is only one thread.
However, if you for example query the database for some information and pass a callback, while the query is executed, node.js can process new requests. Once the database query is completed, node.js calls the callback and finishes processing the first request.
EDIT:
Simple server example:
var http = require('http');
var numresponses = 0;
http.createServer(function (request, response) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('This is response #' + (++numresponses));
}).listen(80);
this server will always print out the number of the request even if two requests happen simultaneously, node will choose one that gets processed first, and both will have different numbers.
OK, can someone tell me what's going on? I have this in my main file:
var http = require('http').createServer(function (req,resp){
console.log("Started");
});
http.listen(1337);
I start the server and console.log doesn't log anything. I load a webpage, and every time I load it, I get the console.log("Started") message. What gives?
The console.log() is run inside the HTTP request listener function, which only runs when the HTTP server receives a request. When you create the server, the listener function isn't invoked, so console.log() doesn't run.
If you want the message to run on HTTP server listen, use it in the listen() function's callback.
server.listen(80, function() {
// this runs when the server has been started
});
I'm trying to make simple http server, that can be pause and resume,, I've looked at Nodejs API,, here http://nodejs.org/docs/v0.6.5/api/http.html
but that couldn't help me,, I've tried to remove event listener on 'request' event and add back,, that worked well but the listen callback call increase every time i try to pause and resume,, here some code i did:
var httpServer = require('http').Server();
var resumed = 0;
function ListenerHandler(){
console.log('[-] HTTP Server running at 127.0.0.1:2525');
};
function RequestHandler(req,res){
res.writeHead(200,{'Content-Type': 'text/plain'});
res.end('Hello, World');
};
function pauseHTTP(){
if(resumed){
httpServer.removeAllListeners('request');
httpServer.close();
resumed = 0;
console.log('[-] HTTP Server Paused');
}
};
function resumeHTTP(){
resumed = 1;
httpServer.on('request',RequestHandler);
httpServer.listen(2525,'127.0.0.1',ListenerHandler);
console.log('[-] HTTP Server Resumed');
};
I don't know quite what you're trying to do, but I think you're working at the wrong level to do what you want.
If you want incoming connection requests to your web server to block until the server is prepared to handle them, you need to stop calling the accept(2) system call on the socket. (I cannot imagine that node.js, or indeed any web server, would make this task very easy. The request callback is doubtless called only when an entire well-formed request has been received, well after session initiation.) Your operating system kernel would continue accepting connections up until the maximum backlog given to the listen(2) system call. On slow sites, that might be sufficient. On busy sites, that's less than a blink of an eye.
If you want incoming connection requests to your web server to be rejected until the server is prepared to handle them, you need to close(2) the listening socket. node.js makes this available via the close() method, but that will tear down the state of the server. You'll have to re-install the callbacks when you want to run again.