i have just started learning node and i am using node-v0.4.11 on Fedora 12. It installed without any errors and i am able to run some basic programs but there are some things i cant figure out
If i create a server at a port and then if i stop node using Ctrl+C
i cannot use that port again for starting a server without restarting
the system.
my code looks like this
var port=8080;
var count=0;
var http=require('http');
var server = http.createServer(function(req, res) {
count++;
console.log('request no '+count+' received');
res.writeHead(200);
res.end('you are at port '+port);
});
server.listen(port);
console.log('server started at port '+port);
Now when i save the file and execute it the server starts. But when i stop the server from the shell , i cannot start the server again at the port i started before(in this case port 8080).This is bad because every time i have to make changes in that file i have to change the port number too.Can i stop this behavior?
EDIT:
This is the error that i get when i try to start the server at the same port again
Server started at 8080
node.js:203
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: listen EADDRINUSE
at errnoException (net_uv.js:557:11)
at Array.<anonymous> (net_uv.js:632:28)
at EventEmitter._tickCallback (node.js:195:26)
i saw the process list after i terminated node using Ctrl+C and i found node was still running. So i killed it and checked the process list again to make sure it was dead and it was(i could not see it in the process list). Now i again tried to start the server at the same port but i got the same error as above.And once i stop the server and make request from the browser the request hangs up for ever(it keeps on waiting).
My next problem is that in the above when the server starts and i make
the first request count is incremented 3 times and i can see 3
messages at the console. This is just for the first request,if i make
more requests count is just incremented once. Whats wrong?
this problem is solved
My next problem is that if i change res.writeHead(200); to
res.writeHead(404); or any other valid status code like 300 node
gives error at the command line but these are valid status codes and
the server should start and respond to each request according the
status code like Not found for 404. What am i doing wrong?
this problem is solved
I am not able to use Firebug's 'Net' tab to monitor requests when i
send requests to the server created by Node. Is there a way to do so?
Thanks for bearing.
i cannot start the server again at the port i started before
You should not be seeing this behavior, and I cannot reproduce it. Do you get an error message when you try to start the server again? What is it? Once you've stopped the server, do you see any node processes in your process list? If so, can you start your server after you kill them?
count is incremented 3 times and i can see 3 messages at the console
Your browser is sending multiple requests. For example, in Chrome, you might get (1) a pre-fetch request (where Chrome downloads the page it thinks you want), (2) the actual page request, and (3) a request for favicon.ico; your Node app is listening for all requests, not just requests to the / URL. After the initial request, the browser caches the favicon, etc. and doesn't need to request them again.
Try adding console.log(req.url); to your callback and see what URLs the browser is asking for.
any other valid status code like 300 node gives error at the command line
I can't reproduce this problem. What error are you receiving?
I am not able to use Firebug's 'Net' tab to monitor requests when i send requests to the server created by Node
I'm also not able to reproduce this. Firebug and other client-side debugging tools don't know or care what technology is running on the server; it just speaks HTTP.
Related
I've been looking for a while in a lot of threads about how to shut down an http server in nodejs.
I couldn't find a simple way to test my web app.
I'm trying to test my server, writing integration test.
I want to simulate errors as well, hence I start the server with different configurations.
For example:
const app = express()
...
app.use('/route', createRouter(argA, argB)
const server = http.createServer(app)
I want to test that if argA throws an error, my server return 500,
as well as argB.
So I want to start the server with a mock of argA that throws,
then close the server and start it again with a mock of argB that throws.
But, the http server of nodejs doesn't close connected sockets,
so I cant do something like this:
beforeEach((done) => server.start(done))
afterEach((done) => server.stop(done))
Where start execute listen and stop execute close.
The server fails to start since the port is already in use.
How can I manage to start and stop the server with different configurations?
I'm trying to create my first report with jsreport. I've followed the documentation, but I'm not able to generate the most simple Hello world.
I've tried:
npm install jsreport
and then create a simple server:
var http = require('http');
var jsreport = require('jsreport');
http.createServer(function (req, res) {
jsreport.render("<h1>Hello world</h1>").then(function(out) {
out.stream.pipe(res);
}).catch(function(e) {
res.end(e.message);
});
}).listen(1337, '127.0.0.1');
The server is running on port 1337.
But if I try to open http://localhost:1337/ nothing happens. I was expecting a page with Hello world.
On the server side, I get on the console:
2018-02-17T10:55:16.009Z - info: Initializing jsreport#1.10.0 in development mode using configuration file: jsreport.config.json
2018-02-17T10:55:16.011Z - info: Setting process based strategy for rendering. Please visit http://jsreport.net/learn/configuration for information how to get more performance.
2018-02-17T10:55:16.013Z - info: Searching for available extensions in /home/jgr/WebstormProjects/GeoMasterBoard/server/
2018-02-17T10:55:16.016Z - info: Extensions location cache not found, crawling directories
Do I need a jsreport server running or this code should be enough?
I also tried to install jsreport server, following the documentation.
After jsreport start it shows on the console:
2018-02-17T10:42:46.013Z - info: Initializing jsreport#1.10.0 in development mode using configuration file: jsreport.config.json
2018-02-17T10:42:46.015Z - info: Setting process based strategy for rendering. Please visit http://jsreport.net/learn/configuration for information how to get more performance.
2018-02-17T10:42:46.023Z - info: Searching for available extensions in /home/jgr/WebstormProjects/GeoMasterBoard/server/
2018-02-17T10:42:46.025Z - info: Extensions location cache not found, crawling directories
But nothing happens when I try to open http://localhost:5488/. If I do: nmap -p 5488 localhost the awnser is:
PORT STATE SERVICE
5488/tcp closed unknown
What am I missing?
I'm using node.js v8.1.2, on Ubuntu 16.04.
your code is not working because the following reasons:
when you open your browser at http://localhost:1337/ your browser is actually making 3 different requests (1-> http://localhost:1337/, 2-> http://localhost:1337/favicon.ico, 3-> http://localhost:1337/robots.txt), not just one
the code that your are using to handle the http server is not doing a proper routing, it should process a url just once, right now it is just calling jsreport.render on every single request that goes through your server (even the ones for /favicon.ico, /robots.txt), and this is bad in the browser because as i already explained your browser makes like 3 request for a single page load.
you are using the shortcut jsreport.render in the request handling, which means that jsreport is going to try to initialize itself when your first request arrives, because of the problem explained above (not doing a proper routing in your http server) this results in jsreport trying to initialize 3 times on your first page load which leads to an uncaught exception that exits your process with no error message (we are going to update some things to better handling this exception in the future).
finally, here is some code that completes your hello world test case (with some code that filters unwanted requests like /robots.txt, /favicon.ico, but in production code you should implement a proper router logic in your http server. if you don't want to code it yourself just use something like express)
var http = require('http');
var jsreport = require('jsreport');
http.createServer(function(req, res) {
if (req.url !== '/') {
return console.log('ignoring request:', req.url);
}
console.log('request:', req.url);
jsreport
.render('<h1>Hello world</h1>')
.then(function(out) {
out.stream.pipe(res);
})
.catch(function(e) {
res.end(e.message);
});
}).listen(1337, '127.0.0.1');
I am studying nodejs and I was following a beginners tutorial.
I followed the instructions and wrote the example code without errors.
When I ran my js file using node it doesn't show or notify if the server is already running on port 3000 like most of the examples do even if it was already running on port 3000.
I then added logging to see if my console was just not displaying log messages from node but it log and displayed properly.
console.log('Requested route: ', req.url);
console.log('Requested method: ', req.method);
What did I do wrong or what do I have to do so it notifies and displays in the console if the server is already running? Sometimes I just stare at the screen and not know if the server has already started or it hanged.
All you have to do is add the console.log call inside of the http.listen block:
http.createServer(router).listen(3000, () => {
console.log('server is running on port 3000');
})
Besides that, I really recommend you to move on and use express-js framework. https://expressjs.com/
Here is a simple script
var http = require("http");
http.get( WEBSITE, function(res) {
console.log("Does not return");
return;
});
if WEBSITE variable is 'http://google.com' or 'http://facebook.com' script does not return to console.
but if WEBSITE variable is 'http://yahoo.com' or 'http://wikipedia.org' it returns to console. What is the difference?
By "return to console" I'm assuming you mean that node exits and drops you back at a shell prompt.
In fact, node does eventually exit for all of those domains you listed. (You were just impatient.)
What you are seeing is the result of HTTP keep-alives. By default, node keeps the TCP connection open after a HTTP request completes. This makes subsequent requests to the same server faster. As long as a TCP connection is still open, node will not exit.
Eventually, either node or the server will close the idle connection (and thus node will exit). It's likely that Google and Facebook allow idle connections to live for longer amounts of time than Yahoo and Wikipedia.
If you want your script to make a request and exit as soon as it completes, you need to disable HTTP keep-alives. You can do this by disabling Agent support.
http.get({ host:'google.com', port:80, path:'/', agent:false }, function(res) {
...
});
Only disable the Agent if you need this specific functionality. In a normal, long-running app, disabling the Agent can cause many problems.
There are also some other approaches you can take to avoid keep-alives keeping node running.
Supposed I have some unit tests that test a web server. For reasons I don't want to discuss here (outside scope ;-)), every test needs a newly started server.
As long as I don't send a request to the server, everything is fine. But once I do, a call to the http server's close function does not work as expected, as all made requests result in kept-alive connections, hence the server waits for 120 seconds before actually closing.
Of course this is not acceptable for running the tests.
At the moment, the only solutions I'd see was either
setting the keep-alive timeout to 0, so a call to close will actually close the server,
or to start each server on a different port, although this becomes hard to handle when you have lots of tests.
Any other ideas of how to deal with this situation?
PS: I had a asked How do I shutdown a Node.js http(s) server immediately? a while ago, and found a viable way to work around it, but as it seems this workaround does not run reliably in every case, as I am getting strange results from time to time.
function createOneRequestServer() {
var server = http.createServer(function (req, res) {
res.write('write stuff');
res.end();
server.close();
}).listen(8080);
}
You could also consider using process to fork processes and kill them after you have tested on that process.
var child = fork('serverModuleYouWishToTest.js');
function callback(signalCode) {
child.kill(signalCode);
}
runYourTest(callback);
This method is desirable because it does not require you to write special cases of your servers to service only one request, and keeps your test code and your production code 100% independant.