I ask the same question in another thread, but the answer misunderstood my question , thus I ask again
I have two scripts
s1.js, s2.js
both use express framework and listen to certain port.
I call
node s1.js //listens to port 8080
node s2.js //listens to port 8081
to start the two scripts, one listens to port 8080, another listens to port 8081.
is it possible to make nodejs scripts listen to same port 8080? how to separate the two scripts when I call
www.abc.com:8080
Your comment welcome
Updated question
I try code app.js
var express = require("express");
var app = express();
app.use('/app1', require( './app1/index.js').app);
app.use('/app2', require( './app2/index.js').app);
app.listen(8081);
in the path ./app1/index.js
var express = require("express");
var app = express();
console.log("app1");
app.listen(8081);
in the path ./app2/index.js
var express = require("express");
var app = express();
console.log("app2");
app.listen(8081);
then I called
node app
console reports error:
app1
/Users/myname/node_modules/express/lib/application.js:111
if (fn.handle && fn.set) app = fn;
^
TypeError: Cannot read property 'handle' of undefined
at Function.app.use (/Users/zhengwang/node_modules/express/lib/application.js:111:9)
at Object.<anonymous> (/Users/zhengwang/multi.js:27:7)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
Cluster does this, and so does Express.vhost. You can in fact use both and only use 1 port all together.
// server.js
var cluster = require('cluster');
var express = require('express');
var app = express ();
var cpus = require('os').cpus().length - 1;
if(cluster.isMaster) {
for(var i=0;i<cpus;i++) {
cluster.fork ();
}
}
else {
app
.use( express.vhost('www.site1.com'), require('./site1.js').app ) )
.use( express.vhost('www.site2.com'), require('./site2.js').app ) )
.listen(8080);
}
In the site1.js, site2.js, you write them out like you'd write any other node app, except for two little things. Export your app (var app = exports.app = express() ), and don't listen (app.listen(8080)) in those two files. You can see the server.js already does the listening for you, and also requires the two 'app' exports from them. Now all your sites on the same server can run on the same port, and on every CPU your server has. I do believe your server itself needs to be setup correctly too, for multiple vhosts, but that's beyond the question asked.
Cluster deals with sending requests to one of the node apps (server.js) running, then express deals with using the right app (site1.js, site2.js) for the request based on the url used. Surprisingly simple I'd say. I do love node.
Okey, so here's the truth: multiple processes can listen on the same port. There are two cases known to me (only on POSIX):
1) Forking. When a master process listens on a socket and then it forks itself then all children listen on the same socket. This means that multiple processes listen on the same socket. And this actually what Node.js cluster does. You might want to have a look at it.
2) Passing socket file descriptor between two independent processes. Yes, it can be done. However there's a lots of work involved with it. Basically two processes communicate via UDS and one of them passes socket file descriptor to the other, so the other can listen on it as well. However this requires some low level network programming (passing a socket's FD is not as simple as passing it as a message). Here's an example of such implementation in C:
http://lists.canonical.org/pipermail/kragen-hacks/2002-January/000292.html
I'm not sure though whether 2) can be done with Node.js.
Note that in both cases it is up to OS to load balance between processes (it is OS that decides which process handles accept
and/or recv
on a socket). As far as I know most OS do their job really well.
However this is really impractical. I've never seen solution 2) used in real life (extremely complex, some serious security issues) and as for solution 1) it was widely used by (for example) Apache web server but nowadays people tend to use threads and/or async systems so forking becomes a bit obsolete (unless you want to take a full advantage of multiple CPU cores - there are no threads in Node.js).
So in your case I guess that the easiest solution would be to put a (ha)proxy in front of both servers so that it will load balance between these two scripts.
Note that the question is weird though. You say that you have two different servers but you want them to listen on the same port. This means that each request will go to one of them. In particular half users will be handled by s1
while the other half by s2
. If they are doing the same that why are there two files? If they are doing something else then why would half of users get different result? It seems that you are trying to do something really bad.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With