Can't capture duplicate port error in Express - node.js

All,
I have a simple Express web server on Windows Node. I can't work out how to capture the error if I'm trying to start the server on the same port as another instance of Express already running. The error middleware won't capture it and the usual .on("error", function ()....) doesn't work either, and the whole Node application bombs - I want to capture it gracefully.
Here is the code:
var express = require('express');
var compression = require('compression')
var app = express();
var __dirname = ""
app.use(compression({ threshold: 512 }));
var oneYear = 86400000 * 365;
app.enable('etag')
app.use(express.static(__dirname + '../../HAWebClient', { maxAge: oneYear }));
app.use(function (err, req, res, next) {
if (!err) return next();
console.log('<-------Error Occured ----->');
res.send(500, JSON.stringify(err, ['stack', 'message']));
});
app.on("error", function (err) {
status("SYSTEM/HTTP", "Error with the web server: " + err);
// Do stuff with error
});
app.listen(80);
and I get
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at errnoException (net.js:904:11)
at Server._listen2 (net.js:1042:14)
at listen (net.js:1064:10)
at Server.listen (net.js:1138:5)
at Function.app.listen (C:\Users\deandob\Documents\GitHub\PluginMgr\PluginMgr\node_modules\express\lib\application.js:546:24)
at webSvr (C:\Users\deandob\Documents\GitHub\PluginMgr\PluginMgr\PlugMgr.js:298:9)
at Object.<anonymous> (C:\Users\deandob\Documents\GitHub\PluginMgr\PluginMgr\PlugMgr.js:271:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
Press any key to continue...
Don't want to capture this in Node's global error handler (which loses error context) - this error should be able to be captured by app.on("error,....) but I'm obviously missing something here. Thanks for the input!

When the port is already in use, app.listen(80); will throw an exception asynchronously (the exception you see in your error log) if you don't have an error handler on the server. The server, in this case, is the return value from app.listen(), not the app object which is why you attempt at handling the error was not working.
Rather than let that exception go to the system which will shut-down your app, you can catch the error and prevent the exception like this:
var server = app.listen(8080);
server.on('error', function(e) {
console.log(e);
// put your code here
});
And, then decide what to do in the error handler. I have tested this solution in a sample server and it does work.
FYI, the relevant documentation is on the socket object here: https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback

Related

Loading the same native module into TWO node.js threads

I have a native C++ module that is spun up by a worker thread from node.js, which works great. From within that node module, I can call my native methods like "AddToLog()" and it works great.
I also need to service web requests, which is my dilemma. So I used express and included a file to start it up on a worker thread. That also works fine - both my native code and the express web server are working at the same time.
However, when I try to 'require' my native module in the file that starts the web server, I get an error that the native module could not be registered.
Have I hit a fundamental limitation where node.js cannot load the same native module on two different worker threads? Or this is as simple as a syntax issue?
My hunch is that I can fix this by making the module context aware, but I'm too new to this to know for sure!
I need the express thread to be able to access the module in order to draw its content. So one thread is running a lighting server that collects data and the other services web requests that describe the current state... if it worked!
// SCRIPT 1
'use strict'
const nightdriver = require('./build/Release/nightdriver.node')
const { Worker } = require('worker_threads');
function startserver()
{
nightdriver.addtolog("[index.js] Starting NightDriver Server");
//nightdriver.startserver();
}
const worker = new Worker("./startweb.js");
nightdriver.addtolog("[index.js] Starting Web Server...");
startserver();
// SCRIPT 2
'use strict'
const nightdriver = require('./build/Release/nightdriver.node')
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World');
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
events.js:167
throw er; // Unhandled 'error' event
^
Error: Module did not self-register.
at Object.Module._extensions..node (internal/modules/cjs/loader.js:736:18)
at Module.load (internal/modules/cjs/loader.js:605:32)
at tryModuleLoad (internal/modules/cjs/loader.js:544:12)
at Function.Module._load (internal/modules/cjs/loader.js:536:3)
at Module.require (internal/modules/cjs/loader.js:643:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.<anonymous> (/Users/dave/OneDrive/Source/Node/nightdriver/startweb.js:2:21)
at Module._compile (internal/modules/cjs/loader.js:707:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:718:10)
at Module.load (internal/modules/cjs/loader.js:605:32)
Emitted 'error' event at:
at Worker.[kOnErrorMessage] (internal/worker.js:332:10)
at Worker.[kOnMessage] (internal/worker.js:342:37)
at MessagePort.Worker.(anonymous function).on (internal/worker.js:279:57)
at MessagePort.emit (events.js:182:13)
at MessagePort.onmessage (internal/worker.js:84:8)

Load Balancer for NodeJS Net Server

I have a following NodeJS server file that is supposed to handle following JSON Message:
If received message as key, send some response.
If received app as key, send some DLL to the client.
Now I am interested in handling multiple clients that will, for this case, send only message as Key in JSON.
Here is the code:
var net = require('net');
var fs = require('fs');
var util = require('util');
var server = net.createServer(function(c) { //'connection' listener
console.log('client connected');
c.on('end', function() {
console.log('client disconnected');
});
c.on('data', function(data) {
var json = JSON.parse(data.toString());
if(json.heartbeat){
if(json.first_fetch === "1"){
c.write("{\"config_changed\":\"true\",\"config\":\"This is some config\"}"); // JSON Message here
}
else{
c.write("{\"config_changed\":\"false\"}");
}
}
else if(json.message){
c.write("{\"success\":\"true\"}");
}
else if(json.app){
fs.exists('apps/'+ json.app + ".dll", function (exists) {
util.debug(exists ? "it's there" : "Its not there");
});
var stats = fs.statSync('apps/'+ json.app + ".dll")
var fileSizeInBytes = stats["size"]
var message = json.app + "\n" + fileSizeInBytes + "\n";
c.write(message);
fs.open('apps/'+ json.app + ".dll","r", function(status, fd){
console.log(fd);
var read_bytes = 0;
var fileStream = fs.createReadStream('apps/'+ json.app + ".dll");
fileStream.on('data',function(chunk){
c.write(chunk);
});
})
}
else
{
c.write("{\"some\":\"error\"}");
}
});
c.on('error', function (e) {
console.log(e);
});
// c.pipe(c);
});
server.listen(1936, function() { //'listening' listener
console.log('server bound');
});
My client will send message as {"message":"This is message"}, and server will send {"success":"true"}. I received following benchmark of the server I created:
One client sent 200000 message in 7 seconds.
Two clients, each sent message in 13/14 seconds.
Three clients, each sent message in 17/17/16 seconds.
The time for each client reduces significantly when they are sending message to one server. I tried to run multiple server at once, but it gave:
events.js:85
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at exports._errnoException (util.js:746:11)
at Server._listen2 (net.js:1156:14)
at listen (net.js:1182:10)
at Server.listen (net.js:1267:5)
at Object.<anonymous> (C:\Users\Dell\Desktop\nodeserver\server.js:54:8)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
If I want to get the performance of 200K in 7 seconds for each of clients, how am I to proceed. I want to run multiple instance of servers, with a load balancer to improve the server efficiency. I am using Windows.
try to use node.js Cluster module for this
https://nodejs.org/api/cluster.html
different nodejs instances can't share same port
another approach is to use external load balancer, nginx for example
http://nginx.org/en/docs/http/load_balancing.html

NodeJsApp - Unable to make successful http connections

I'm as new to Node and when I trying to run my first ever simple node app that makes an http connection to www.google.com host. While I tried some of the solutions suggested on prior threads nothing really seemed to help. While the below error is not a rare case but need someone to advise me what's missing from my setup/env.
source code - test.js - as simple as below -
var http = require('http');
var options = { host: 'www.google.com'};
http.get(options, function(err, res) {
console.log("GOT ERR?", err);
console.log("GOT RES?", res);});
I get the below error.
events.js:72
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND
at errnoException (dns.js:37:11)
at Object.onanswer [as oncomplete] (dns.js:124:16)
Your callback is wrong. Try to write your code as follow:
var http = require('http');
var options = { host: 'www.google.com'};
// notice that the callback only receives a res parameter
// errors are handled on an event below
var req = http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
});
// handle errors
req.on('error', function(e) {
console.log("Got error: " + e.message);
});
Here is the documentation for http.get: http://nodejs.org/api/http.html#http_http_get_options_callback
The error that you are seeing (throw er; // Unhandled 'error' event) is because you do not have an even handler for the error event. Notice the req.on('error') in my code to address this.

Express module error while listening http server in nodejs

I have created a nodejs http server
var http = require("http");
var url = require("url");
var express = require('express');
var app = express();
function start(route, handle){
function onRequest(request,response){
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
route(handle, pathname, response, request);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started");
app.listen(8888);
console.log('Express app listening on port 8888');
}
it gives error
f:\Labs\nodejs\webapp>node index.js
Server has started
Express app listening on port 8888
events.js:66
throw arguments[1]; // Unhandled 'error' event
^
Error: listen EADDRINUSE
at errnoException (net.js:769:11)
at Server._listen2 (net.js:909:14)
at listen (net.js:936:10)
at Server.listen (net.js:985:5)
at Function.app.listen (f:\Labs\nodejs\webapp\node_modules\express\lib\appli
cation.js:532:24)
at Object.start (f:\Labs\nodejs\webapp\server.js:15:6)
at Object.<anonymous> (f:\Labs\nodejs\webapp\index.js:11:8)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
when i change the port of app.listen it dont throw this error, what can be done?
will changing port other than server port will keep the session of the server on another port??
and how can i access this app variable in other js page to get/set the data?
If you intend to run on the same port, you can see if you have currently running node processes with
ps aux | grep node
and then kill -9 PROCESSID
You can't have multiple things listening on the same port like this, hence the EADDRINUSE error. If you want to create your own http server while using Express, you can do it like this:
var express = require('express');
var https = require('https');
var http = require('http');
var app = express();
http.createServer(app).listen(8888);
https.createServer(options, app).listen(443);
From the Express docs:
The app returned by express() is in fact a JavaScript Function,
designed to be passed to node's http servers as a callback to handle
requests.
Or you can just do
app.listen(8888);
And then Express will setup an http server for you.
You would then set up your routes in Express to actually handle requests coming in. With Express, routes look like this:
app.get('/foo/:fooId', function(req, res, next) {
// get foo and then render a template
res.render('foo.html', foo);
});
If you want to access your app in other modules (usually for testing) you can just export it like any other variable:
module.exports.app = app;
You'll then be able to require('./app').app in other modules.

How to get Node.JS Express to listen only on localhost?

I have an application that I have behind a reverse proxy, I would like for it to only listen to localhost/127.0.0.1.
I expected this to work:
app.listen(3001, 'localhost');
or
app.listen(3001, '127.0.0.1');
...but instead I get an error:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Cannot read property 'port' of null
at Object.<anonymous> (/home/ctoledo/hive-go/go.js:204:76)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Array.0 (module.js:479:10)
at EventEmitter._tickCallback (node.js:192:40)
Running the application without a specifying the hostname works fine, ie., app.listen(3001);.
I am running Node v0.6.14 and express#2.5.5 and have read this google groups discussion and have found this comment in Express application.js saying: "This method takes the same arguments as node's http.Server#listen()."
Thanks for any help.
Thanks for the info, think I see the problem. This is a bug in hive-go that only shows up when you add a host. The last lines of it are:
app.listen(3001);
console.log("... port %d in %s mode", app.address().port, app.settings.env);
When you add the host on the first line, it is crashing when it calls app.address().port.
The problem is the potentially asynchronous nature of .listen(). Really it should be doing that console.log call inside a callback passed to listen. When you add the host, it tries to do a DNS lookup, which is async. So when that line tries to fetch the address, there isn't one yet because the DNS request is running, so it crashes.
Try this:
app.listen(3001, 'localhost', function() {
console.log("... port %d in %s mode", app.address().port, app.settings.env);
});
You are having this problem because you are attempting to console log app.address() before the connection has been made. You just have to be sure to console log after the connection is made, i.e. in a callback or after an event signaling that the connection has been made.
Fortunately, the 'listening' event is emitted by the server after the connection is made so just do this:
var express = require('express');
var http = require('http');
var app = express();
var server = http.createServer(app);
app.get('/', function(req, res) {
res.send("Hello World!");
});
server.listen(3000, 'localhost');
server.on('listening', function() {
console.log('Express server started on port %s at %s', server.address().port, server.address().address);
});
This works just fine in nodejs v0.6+ and Express v3.0+.

Resources