是否可以使nodejs脚本侦听相同的端口

时间:2013-12-31 10:55:57

标签: node.js

我在另一个帖子中问同样的问题,但答案误解了我的问题,所以我再问一次

我有两个脚本

 s1.js, s2.js

都使用express框架并听取某个端口。

我打电话

node s1.js //listens to port 8080

node s2.js //listens to port 8081

启动这两个脚本,一个侦听端口8080,另一个侦听端口8081。

是否可以使nodejs脚本侦听同一端口8080? 我打电话时如何分开两个脚本

www.abc.com:8080

您的评论欢迎

更新了问题

我尝试代码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);

在路径./app1/index.js

  var express = require("express");
  var app = express();
  console.log("app1");
  app.listen(8081);

在路径./app2/index.js

  var express = require("express");
  var app = express();
  console.log("app2");
  app.listen(8081);
然后我打电话给

  node app

控制台报告错误:

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

3 个答案:

答案 0 :(得分:4)

群集执行此操作,Express.vhost也是如此。事实上,您可以同时使用两个端口,只能一起使用1个端口。

// 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);
}

在site1.js,site2.js中,你写出来就像你写任何其他节点应用程序,除了两件小事。导出你的应用程序(var app = exports.app = express()),并且不要在这两个文件中监听(app.listen(8080))。您可以看到server.js已经为您监听,并且还需要从它们输出两个“app”。现在,同一服务器上的所有站点都可以运行在同一个端口上,也可以运行在服务器所拥有的每个CPU上。我相信你的服务器本身也需要正确设置,对于多个虚拟主机,但这超出了提出的问题。

群集处理向运行的其中一个节点应用程序(server.js)发送请求,然后根据使用的URL为请求表达使用正确应用程序(site1.js,site2.js)的交易。令人惊讶的简单,我会说。我喜欢节点。

答案 1 :(得分:3)

Okey,所以这是事实:多个进程可以在同一个端口上侦听。我知道有两种情况(仅限POSIX):

1)分叉。当主进程侦听套接字然后它自己分叉时,所有子进程都在同一个套接字上侦听。这意味着多个进程侦听同一个套接字。这实际上是Node.js cluster的作用。你可能想看看它。

2)在两个独立进程之间传递套接字文件描述符。是的,可以做到。然而,它涉及很多工作。基本上两个进程通过UDS进行通信,其中一个进程将套接字文件描述符传递给另一个进程,因此另一个进程也可以监听它。然而,这需要一些低级网络编程(传递套接字的FD并不像将其作为消息传递那么简单)。以下是C:

中此类实现的示例

http://lists.canonical.org/pipermail/kragen-hacks/2002-January/000292.html

我不确定2)是否可以用Node.js完成。

请注意,在这两种情况下,操作系统都需要在进程之间进行负载平衡(操作系统决定哪个进程在套接字上处理accept和/或recv。据我所知,大多数操作系统都能很好地完成工作。

然而,这实在是不切实际。我从未见过在现实生活中使用过的解决方案2(非常复杂,一些严重的安全问题)和解决方案1)它被(例如)Apache Web服务器广泛使用但现在人们倾向于使用线程和/或异步系统因此分叉变得有点过时(除非你想充分利用多个CPU核心 - Node.js中没有线程)。

因此,在您的情况下,我认为最简单的解决方案是将(ha)代理放在两台服务器的前面,以便在这两个脚本之间实现负载平衡。

请注意,问题很奇怪。您说您有两个不同的服务器,但您希望它们在同一端口上侦听。这意味着每个请求都将转到其中一个请求。特别是一半用户将由s1处理,而另一半用户将由s2处理。如果他们做同样的事情,为什么有两个文件?如果他们正在做其他事情那么为什么有一半的用户会得到不同的结果?您似乎正在尝试做一些真的糟糕的事情。

答案 2 :(得分:0)

你的/app1/index.js和/app2/index.js不应该监听(),因为app.js已经在监听,他们都需要导出app对象。

var express = require("express");
var app = exports.app = express();
console.log("app1");

同样适用于app2 / index.js

var express = require("express");
var app = exports.app = express();
console.log("app2");